The following code doesn't give the expected minimum -1. Instead I get 0.
Do you know why?
class MainClass
{
public static void Main (string[] args)
{
string numbers = "-1 0 1 2 3 4 5";
Console.WriteLine (numbers.Split (' ')[0]); // output: -1
string max = numbers.Split(' ').Max();
string min = numbers.Split(' ').Min();
Console.WriteLine("{0} {1}", max, min); // output: "5 0"
}
}
I've not fully defined an answer yet but it appears to be because the - isn't accounted for.. you can confirm this with CompareOrdinal
Console.WriteLine(String.CompareOrdinal("-1", "0")); // -3 meaning -1 min
Console.WriteLine(String.Compare("-1", "0")); // 1 meaning 0 min
Either way, you are trying to compare numbers so you should treat them as numbers so similar subtleties dont appear.
Attempted explanation...
String implements IComparable<string> so String.Min uses that implementation (see remarks). Which in turn uses CompareTo,
Now in the notes for this method
Character sets include ignorable characters. The CompareTo(String) method does not consider such characters when it performs a culture-sensitive comparison. For example, if the following code is run on the .NET Framework 4 or later, a comparison of "animal" with "ani-mal" (using a soft hyphen, or U+00AD) indicates that the two strings are equivalent.
(Emphasis mine)
As you see. the - is ignored hence 0 which has a smaller value in an ascii table is used for the comparison
It's a string so Getting max from string is totally different than getting max from a number. For instance if You would have an array like below
char[] someCharArray = new char[] { '1', '12', '2' }
calling Max() on this array would result with 2 as 2 is "higher" in string order than 12.
Thinking about Max/Min value from string/char You need to think about alphabetical order. If You have a colection of letters A-Z, calling Min() will return A, calling Max() will return Z.
To get Max/Min in numerical order You need to cast to some Number type like int.
See below:
string numbers = "-1 0 1 2 3 4 5";
int min = numbers.Split(' ').Select(x => int.Parse(x)).Min();
Console.WriteLine(min); // gives You -1
There are two reasons for this behaviour:
You are sorting strings instead of numbers. This means that behind the scenes, Linq is using String.CompareTo() to compare the strings.
String.CompareTo() has special behaviour for -, which it treats as a HYPHEN and not a MINUS. (Note: This hyphen should not be confused with a soft hyphen which has the character code U00AD.)
Consider this code:
Console.WriteLine("-1".CompareTo("0")); // 1
Console.WriteLine("-1".CompareTo("1")); // 1
Console.WriteLine("-1".CompareTo("2")); // -1
Notice how, counter-intuitively, the "-1" is AFTER "0" and "1" but BEFORE "2".
This explains why when ordering the strings, the "-1" is neither the max nor the min.
Also see the answer to this question for more details.
Related
thank you for taking the time to read this.
I'm working on a larger project that needs a function that generates all numbers based on the rules described in the title.
If inputs are M=3 and N=5 Outputs should be: 111,112,113,114,115,121....555
For inputs M=4 and N=2 Outputs should be: 1111,1112,1121...2222
I've been trying to make a function that does this for quite some time but i haven't succeeded. So I'm asking for help. I'm required to write it in C, but if you know how to fix it in C++ or C# I'll probably be able to translate it into C.
I don't have any code to show because thus far I've mostly tried brute-forcing it but it doesn't seem to work
Thank you for the help in advance!
If I understand the question, I would do it with regular expressions. This is all written with C in mind.
First build a regex with all the allowed digits. Posix provides a regex library (https://www.educative.io/edpresso/how-to-write-regular-expressions-in-c appears to be a good intro), so you only have to compose the string that will be parsed by regcomp() by iterating through the numbers from 1 to N. An appropriate regular expression would be, for N=20, ^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20)+$. This will match strings composed entirely of any of those characters. (Since 0 should match only after 1 or 2 in this case, enumerating the options is simpler than trying to shorten the regex).
Then, iterate over the numbers starting with 10 ^ M and ending when you reach 10^(M+1). Write each number out as a string and see if it matches the regular expression - if it does, you have one of your results.
The problem can be boiled down to starting an M-digit, base-N number at its lowest value for the initial iteration, and incrementing it for subsequent iterations.
The M-digit number can be represented as an array (indexed from 0 to M-1) with one element per digit. One end of the array will hold the lowest order ("rightmost") digit and the other end of the array will hold the highest order ("leftmost") digit. It doesn't really matter which end is chosen to hold the highest order digit, so let's choose element 0 to hold the highest order digit. For generality, let's use digit values from 0 to N-1. (It doesn't really matter that the original problem has digits going from 1 to N since it is easy to map digit values from one scheme to the other.)
We can define a function to set the M-digit number to its lowest value:
void num_init(unsigned int *digits, unsigned int m)
{
while (m--)
{
digits[m] = 0;
}
}
We can define another function to increment the M-digit number and indicate whether the number has wrapped around back to its lowest value:
int num_inc(unsigned int *digits, unsigned int n, unsigned int m)
{
while (m--)
{
if (digits[m] < n - 1)
{
digits[m]++;
return 0;
}
digits[m] = 0; // carry
}
return 1;
}
Example usage:
// Print all M-digit numbers with digits from 1 to N.
void list_nums(unsigned int m, unsigned int n)
{
unsigned int digits[m];
int wrapped = 0;
num_init(digits, m);
while (!wrapped)
{
unsigned int i;
// output an m-digit number
for (i = 0; i < m; i++)
{
// Note: Add 1 to each digit so digits run from 1 to n instead of 0 to n-1.
printf("%u", digits[i] + 1);
}
// get next number
wrapped = num_inc(digits, n, m);
if (!wrapped)
{
printf(",");
}
}
printf("\n");
}
Note: The output of list_nums(m, n) will be strange when n is greater than 9.
I need to generate a 4 bit string randomly and set to a property via Linq.
Right now is hardcoded:
// TODO: hardcode bit string
employees = employees.Select(x => { x.Options = "0101"; return x; }).ToList();
I need Options to be random so I can get all 4 bit possible values: "0001","0010", "0011" and so on.
I was thinking on having a Random 0 to 1 variable and generate the value 4 times and concatenate the string.
Any clue on how to implement this?
If speed is critical, such as this operating being called in a loop, it would be more efficient to use a 16 element string array of all possible values and select the element randomly.
var rand = new Random();
Convert.ToString(rand.Next(16), 2).PadLeft(4, '0')
Explanation:
The first line creates a random object, nothing too hard to understand here... The second line first generates a random number between 0 - 15 (rand.Next(16)). Then it puts the random number into Convert.ToString. The method converts to number to base 2 (because the second parameter is 2). However, this still is not enough because if the random number can be represented by 3 bits or fewer, the returned string will not have the leading 0s. That's why I used PadLeft to add them in.
You can use this
Convert.ToString(int, 2);
This will convert the int to base 2 string.
Where int is a random number up to 16 not included.
8654 -> 8653; 1000 -> 0999; 0100 -> 0099; 0024 -> 0023; 0010 -> 0009; 0007 -> 0006 etc.
I have a string variable of fixed length 4; its characters are always numbers. I want to make subtraction while obeying the given rule that its length of 4 must be protected.
What I tried: Convert.ToInt32, .Length operations etc. In my code, I always faced some sort of errors.
I devised that I can do this via 3 steps:
1. Convert the string value to an (int) integer
2. Subtract "1" in that integer to find a new integer
3. Add "4 - length of new integer" times "0" to the beginning.
Anyway, independent of the plotted solution above (since I am a newbee; perhaps even my thought may divert a standard user from a normal plausible approach for solution), is not there a way to perform the above via a function or something else in C#?
A number doesn't have a format, it's string representation has a format.
The steps you outlined for performing the arithmetic and outputting the result are correct. I would suggest using PadLeft to output the result in the desired format:
int myInt = int.Parse("0100");
myInt = myInt - 1;
string output = myInt.ToString().PadLeft(4, '0');
//Will output 0099
Your steps are almost right, however there is a easier way to accomplish getting the leading 0's, use Numeric string formatting. Using the formatting string "D4" it will behave exactly like you want.
var oldString = "1000";
var oldNum = Convert.ToInt32(oldString);
var newNum = oldNum - 1;
var newString = newNum.ToString("D4");
Console.WriteLine(newString); //prints "0999"
Click to run example
You could also use the custom formatting string "0000".
Well, I think others have implemented what you have implemented already. The reason might be that you didn't post your code. But none of the answers addresses your main question...
Your approach is totally fine. To make it reusable, you need to put it into a method. A method can look like this:
private string SubtractOnePreserveLength(string originalNumber)
{
// 1. Convert the string value to an (int) integer
// 2. Subtract "1" in that integer to find a new integer
// 3. Add "4 - length of new integer" times "0" to the beginning.
return <result of step 3 >;
}
You can then use the method like this:
string result = SubtractOnePreserveLength("0100");
// result is 0099
How do I remove for example 2 from 123 and returns 13, by using bitwise operators? I have no idea how to do this.. it's possible? Thanks in advance.
What you're suggesting is possible, but wouldn't really make sense to do. Below are the values representations in bits (only showing relevant bits, everything further left is a zero):
2: 000010 || 123: 1111011 || 13: 001101
There's no logical way to change 123 into 13 with bitwise operations. It would better to turn it into a string or character array, remove the two then cast it back to an int.
What other cases are there? It may be possible to generalize this at an integer level if there is some sort of pattern, otherwise you're really just looking at string replacement.
The 2 in 123 is actually 2E1 (10100), and the 2 in 1234 would be 2E2 (11001000) neither of which are related to 2 (10), at least in bitwise form. Also, the "number" on the right side of the removed number would need to be added to the number on the left side of the removed number / 10.
i.e, to go from 123 to 13:
Located "2".
Number on left (x): 100
Number on right (y): 3
y + (x / 10) = 13
and to go from 1324 to 134
Located "2"
Number on left (x): 1300
Number on right (y): 4
y + (x / 10) = 134
Unless there's some pattern (i.e you know what positions the numbers are in), you'll just have to .ToString() the number, then do a .Replace("2", ""), before doing an int.Parse() on the result.
EDIT: Someone upvoted this answer and I realised my previous implementation was unnecessarily complicated. It is relatively straightforward to 'iterate' over the digits in a base-10 number and shouldn't require recursion.
New solution below, performance is better but this is a huge micro-optimisation:
static int OmitDigit(int number, int digit) {
var output = 0;
var multiplier = 1;
while (number > 0) {
var n = number % 10;
number /= 10;
if (n != digit) {
output += (n * multiplier);
multiplier *= 10;
}
}
return output;
}
Result:
1554443
Since we're working with base 10 numbers, manipulation in base 2 is ugly to say the least. Using some math, removing the nth digit from k, and shifting over is
(k/pow(10,n))*pow(10, n-1) + k%pow(10, n-1)
In base 2, the << and >> operator acts like multiplying by a pow(2, n), and & with a mask does the work of %, but in base 10 the bits don't line up.
This is very awkward, but if you really do must have bitwise operations only, I suggest you convert the number to BCD. Once in BCD, you basically have an hexadecimal numbers with digits between 0 and 9, so removing a digit is very simple. Once you're done, convert back to binary.
I don't believe anybody would want to do that.
I need to apply validation on input time intervals that are taken in as seconds. Now i am not really good at Regular expressions. So can any body help making a regular expression that can test whether a number is divisible by 60.
I was wondering if i could use to test one that check that the number is divisible by 10 and then check whether the same is divisible by 6.
For number divisible by 10 here [\d*0] is the expression i guess. Please correct me if i am wrong.
Hope somebody solves my problem.
Thanks
Why not do N % 60 ?
Why you want to use regex for a job which can easily be done using one operator ?
As others have mentioned, regular expressions are completely the wrong tool to use for this. Rather, use TryParse to convert the string to an integer, and then test whether the integer is divisible by 60.
That said, it is instructive to see how this could possibly work with a regexp.
First off, of the one-digit numbers, only 0 is evenly divisible by 60. Of the non-one-digit numbers, all numbers divisible by 60 are also divisible by 20, and therefore end in 00, 20, 40, 60 or 80. That is easily tested with a regexp.
Suppose it passes the first test. We know from this test that the number is divisible by 20. Now all we need to do is show that it is divisible by 3. If it is, then it is divisible by both 20 and 3 and therefore must be divisible by 60, since 20 and 3 are coprime.
So we need a regular expression that can determine if a number is divisible by 3.
It is well known that numbers divisible by three are such that the sum of their digits is divisible by 3.
It is also well known that every regular expression corresponds to a finite state machine, and every finite state machine corresponds to a regular expression.
Therefore if we can come up with a finite state machine that determines divisibility by three, we're done.
This is easily done. Our finite state machine has three states, A, B and C. The start state is A. The accepting state is A. The transitions are:
When in state A, inputs 0, 3, 6 and 9 go to state A. Inputs 1, 4 and 7 go to state B. Inputs 2, 5 and 8 go to state C.
When in state B, inputs 0, 3, 6 and 9 go to state B. Inputs 1, 4 and 7 go to state C. Inputs 2, 5 and 8 go to state A.
When in state C, inputs 0, 3, 6 and 9 go to state C. Inputs 1, 4 and 7 go to state A. Inputs 2, 5 and 8 go to state B.
All other inputs go to an error state.
And we're done; we have a finite state machine that checks for divisibility by 3. Therefore we can build a regexp that checks for divisibility by 3; if we combine that with the regexp that checks for divisibility by 20, then we have the desired regular expression. The language of numbers written in decimal notation divisible by 60 is a regular language.
The actual construction of such a regular expression is left as an exercise. (Looks like that's what tiftik has done.)
Exercise: can you come up with a regular expression that determines if string contains a decimal number that is evenly divisible by 70? If you can, let's see it. If not, can you provide a proof that no such regular expression exists? (That is, that the language I am describing is not regular.)
I've come up with this:
^((?=[^147]*(([147][^147]*){3})*$)(?=[^258]*(([258][^258]*){3})*$)|(?=[^147]*(([147][^147]*){3})*[147][^147]*$)(?=[^258]*(([258][^258]*){3})*[258][^258]*$)|(?=[^147]*(([147][^147]*){3})*([147][^147]*){2}$)(?=[^258]*(([258][^258]*){3})*([258][^258]*){2}$))\d*0(?<=[02468][048]|[13579][26]|^0)$
Note: I didn't use non-capturing groups for the sake of simplicity.
Edit: Shorter version:
^(?=[^147]*(?:(?:[147][^147]*){3})*(?:()|([147][^147]*)|((?:[147][^147]*){2}))$)(?=[^258]*(?:(?:[258][^258]*){3})*(?:()|([258][^258]*)|((?:[258][^258]*){2}))$)((?(1)(?(4)|.$)|.$)|(?(2)(?(5)|.$)|.$)|(?(3)(?(6)|.$)|.$))\w*0(?<=[02468]0|^0)$
(+,/,-,*) in Regex are not used as mathematical operators. Use JavaScript instead.
Note: Regular expressions are not the right tool for this. This is just for fun and to see how it could be done.
Here is a regular expression that tests if a number is divisible by 60:
^0$|^(?!0)(?=.*[02468]0$)(?:[0369]|[147](?:[0369]*[147][0369]*[258])*(?:[0369]*[258]|[0369]*[147][0369]*[147])|[258](?:[0369]*[258][0369]*[147])*(?:[0369]*[147]|[0369]*[258][0369]*[258]))*0$
It works by testing if the number is divisible by 3 and using a lookahead to check if it is divisble by 20. It differs from the regular expression posted by tiftik in the following ways:
It is slightly shorter.
It uses non-capturing groups.
Many languages (for example Javascript )don't support variable length lookbehind assertions. This regular expression does not use lookbehinds so it can for example also be used for client-side validation in a web application.
It disallows numbers with leading zeros (if you want to allow leading zeros just remove the (?!0)).
This is the code I used to generate and test it:
using System;
using System.Text;
using System.Text.RegularExpressions;
class Program
{
Regex createRegex()
{
string a = "[0369]*";
string b = "a[147]";
string c = "a[258]";
string r = "^0$|^(?!0)(?=.*[02468]0$)(?:[0369]|[147](?:bc)*(?:c|bb)|[258](?:cb)*(?:b|cc))*0$";
r = r.Replace("b", b).Replace("c", c).Replace("a", a);
return new Regex(r);
}
bool isDivisibleBy3(string s)
{
int sumOfDigits = 0;
foreach (char c in s)
{
sumOfDigits += c - '0';
}
return sumOfDigits % 3 == 0;
}
bool isDivisibleBy20(string s)
{
return Regex.IsMatch(s, "^0$|[02468]0$");
}
bool isDivisibleBy60(string s)
{
return isDivisibleBy3(s) && isDivisibleBy20(s);
}
bool isValid(string s)
{
return Regex.IsMatch(s, "^0$|^[1-9][0-9]*$");
}
void Run()
{
Regex regex = createRegex();
Console.WriteLine(regex);
// Test on some random strings.
Random random = new Random();
for (int i = 0; i < 100000; ++i)
{
int length = random.Next(50);
StringBuilder sb = new StringBuilder();
for (int j = 0; j < length; ++j)
{
sb.Append(random.Next(10));
}
string s = sb.ToString();
bool isMatch = regex.IsMatch(s);
bool expected = isValid(s) && isDivisibleBy60(s);
if (isMatch != expected)
{
Console.WriteLine("Failed for " + s);
}
}
}
static void Main()
{
new Program().Run();
}
}
Regular expressions are the wrong tool for this job. Instead, try dividing by 60 and see if there is no remainder:
if (value % 60 == 0) {
// is divisible by 60
// ... do something ...
}