C# scale program help(easy) - c#

I'm looking to make a program that calculates the sum of 7 numbers. But with a twist. IF one of these variables is smaller than 84 OR greater than 184, then this one variable is counted out of the sum of the other 6 numbers.
So lets say for example:
a=50
b=51
c=90
d=91
e=92
f=93
g=94
So now it would be; c+d+e+f+g. Do I need to do this with 1000 "If" sentences?

If you are not allowed to use loops then perhaps the next easiest way it to create a function and use that instead of +. I am going to assume then that you are also not allowed to use other slightly more complex concepts like classes ect.
public int ValueTest(int iValue)
{
if ((iValueTwo > 84) && (iValueTwo < 184) {
return iValue;
}
return 0;
}
static int Main(string[] args)
{
int a=50;
int b=51;
int iResult = 0;
iResult = ValueTest(a) + ValueTest(b);
Console.WriteLine("Result is: ", iResult);
return 0;
}
I have only done two values but this should give you the idea. Also I haven't tested this code so I may have missed something small but the general idea should still be sound.
Cheers

Do I need to do this with 1000 "If" sentences?
No, just 7
int total = 0;
if(a >= 84 && a <= 184)
total += a;
.. etc

One-liner (or rather a single statement formatted to fit here):
int total = ((a >= 84 && a <= 184) ? a : 0) +
((b >= 84 && b <= 184) ? b : 0) +
((c >= 84 && c <= 184) ? c : 0) +
((d >= 84 && d <= 184) ? d : 0) +
((e >= 84 && e <= 184) ? e : 0) +
((f >= 84 && f <= 184) ? f : 0) +
((g >= 84 && g <= 184) ? g : 0);
Or you could do it with LINQ (if that's allowed):
int total = new {a, b, c, d, e, f, g}.Where(x => x >= 84 && x <= 184).Sum();

Related

C# Input Value how to validate from A to ZZZ

Input Value can be from A to ZZZ (only alphabetical, no numeric characters) how can I validate a from and to field.
Where the input can be A or AA or AAA
B > A
BB > A
BBB > A
BBB < B
BBB < BB
DD > C
but then D should be < CC fails because it is not a lexicographical order
I was thinking check the length first because if the from length is less than to length then it will always be less. If equal in length then an alphabetical check. Then I come unstuck.
Not simple lexicographical order because three possiable groups single, double, triple chars single group lower than double and triple group and double lower than triple group not just alphabetical.
have you thought about using a regexp? \b[A-Z]{1,3}\b
You can do the following: Imagine the String AAA as a number, saying A*26^2 + A*26^1 + A*26^0
(Base 26, because there are that much letters)
Split the String, Cast values A to Z to 1 to 26 (WhiteSpace in front = 0) and you are done:
A = 0*26^2 + 0*26^1 + 1*26^0 => 1
B = 2 => 2
...
Z = 26 => 26
AA = 1 * 26^1 + 1 => 27
...
ZZ = 26*26^1 + 26 = 702
...
ZZZ = 26*26^2 + 26*26^1 + 26 => 18278
wrap it Like
public int LetterCodeToInt(String LetterCode)
{
//fill up whitespaces in front.
String s = LetterCode.PadLeft(3, '_').ToUpper();
int value = 0;
int k = s.Length -1;
for (int i = 0; i < s.Length; i++)
{
if (s[i] != '_')
{
//ASCII "A" is 65, subtract 64 to make it "1"
value += (((int)s[i]) - 64) * Convert.ToInt32(Math.Pow(26, k));
}
k--;
}
return value;
}
and you can do:
if (LetterCodeToInt("AAA") > LetterCodeToInt("AZ")){
}
string from = "BB";
string to = "AAA";
bool valid = string.Compare(from, to) < 0; // false
So it works already in lexicographical order. Demo
You're on the right track. Create a custom comparer that checks the length first. For example:
public class MyComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x.Length < y.Length) return -1;
if (x.Length > y.Length) return 1;
return Comparer.Default.Compare(x, y);
}
}

c# minimum of two numbers if one or both is greater than 0

The logic I'm looking for is if either of the numbers are >= 0 (which they don't have to be), then return the minimum of the two that is also greater than 0. The code I've written for it is so ugly that I'm ashamed to post it!
EDIT:
Samples
1, -1 => 1
5,6 => 5
-1,-1 => 0
(if both are less than 0, return 0)
I'm going to try my psychic powers, and assuming that if both are zero, you want to return 0.
In other words:
return x < 0 && y < 0 ? 0
: x < 0 ? y
: y < 0 ? x
: Math.Min(x, y);
I'm sure I can do better though...
If they're not both greater than 0, then at least one will be less than zero, so you just care about the greater of them, or 0 if they're both less than zero. Otherwise, we just take the minimum.
return x < 0 || y < 0 ? Math.Max(Math.Max(x, y), 0) : Math.Min(x, y);
If you don't care much about performance, you could use:
new[] { x, y }.Where(z => z > 0)
.DefaultIfEmpty() // Make sure there's at least one entry
.Min();
Frankly none of these are terribly nice, IMO. I'd want a comment with any of them...
Is this too ugly?
private int GetSmallestNonNegative(int a , int b)
{
if (a >= 0 && b >= 0)
return Math.Min(a,b);
else if (a >= 0 && b < 0)
return a;
else if (a < 0 && b >= 0)
return b;
else
return 0;
}
I think this is simple, extendable to any number arguments, and reflects the original wording of the question ("minimum of a set of numbers that is also greater than or equal to 0") reasonably well:
new[] { a,b,0 }.Where(x => x >= 0).Min();
If (a>=0 &&b>=0)
return Math.Min(a,b);
var min =Math.Max(a,b);
return min<0 ? 0: min;
return (a >=0 && b>=0) ? Math.Min(a,b) : (Math.Max(a,b) < 0 ? 0 : Math.Max(a,b));
return (a >= 0 || b >= 0) ? Math.Min(Math.Max(0,a), Math.Max(0,b)) : 0;
(edit) small change for slightly better performance when either are zero
return (a > 0 || b > 0) ? Math.Min(Math.Max(0,a), Math.Max(0,b)) : 0;
try (although no beauty):
Math.Max (Math.Sign (Math.Max (x,0)), Math.Sign (Math.Max (y, 0))) == 0 ? 0 : ((Math.Sign (Math.Max (x,0)) + Math.Sign (Math.Max (y, 0))) == 2 ? Math.Min (x, y): Math.Max (x, y ))
I hope this will be helpful.
Max= ((num1+num2)+Math.Abs(num1-num2))/2
and Min= ((num1+num2)-Math.Abs(num1-num2))/2
Now that we have new C# features, you could use switch expressions and ValueTuple pattern matching to only test each variable once:
var ans = (x < 0, y < 0) switch {
(true, true) => 0,
(false, true) => x,
(true, false) => y,
(false, false) => Math.Min(x, y)
};
You could also flip the tests around, depending on which is more important or you think is more readable:
var ans = (x >= 0, y >= 0) switch {
(false, false) => 0,
(true, false) => x,
(false, true) => y,
(true, true) => Math.Min(x, y)
};

How do I check the validity of the Canadian Social Insurance Number in C#?

I've been given the assignment to write an algorithm in C# that checks the validity of a Canadian Social Insurance Number (SIN). Here are the steps to validate a SIN.
Given an example Number: 123 456 782
Remove the check digit (the last digit): 123456782
Extract the even digits (2,4,6,8th digith): 12345678
Double them:
2 4 6 8
| | | |
v v v v
4 8 12 16
Add the digits together: 4+8+1+2+1+6 = 22
Add the Odd placed digits: 1+3+5+7 = 16
Total : 38
Validity Algorithm
If the total is a multiple of 10, the check digit should be zero.
Otherwise, Subtract the Total from the next highest multiple of 10 (40 in this case)
The check digit for this SIN must be equal to the difference of the number and the totals from earlier (in this case, 40-38 = 2; check digit is 2, so the number is valid)
I'm lost on how to actually implement this in C#, how do I do this?
This is a nice problem to solve. This should be more efficient than converting to string and parsing back to integer. This solution will work on .NET 3.5 and later.
public static IEnumerable<int> ToDigitEnumerable(this int number)
{
IList<int> digits = new List<int>();
while(number > 0)
{
digits.Add(number%10);
number = number/10;
}
//digits are currently backwards, reverse the order
return digits.Reverse();
}
public static bool IsCanadianSocialInsuranceNumber(int number)
{
var digits = number.ToDigitEnumerable();
if (digits.Count() != 9) return false;
//The left side of the addition is adding all even indexes (except the last digit).
//We are adding even indexes since .NET uses base 0 for indexes
//The right side of the addition, multiplies the odd index's value by 2, then breaks each result into
//individual digits, then adds them together
var total = digits.Where((value, index) => index%2 == 0 && index != 8).Sum()
+ digits.Where((value, index) => index%2 != 0).Select(v => v*2)
.SelectMany(v => v.ToDigitEnumerable()).Sum();
//The final modulous 10 operator is to handle the scenarios where the total
//is divisble by 10, in those cases, the check sum should be 0, not 10
var checkDigit = (10 - (total%10)) % 10;
return digits.Last() == checkDigit;
}
One problem with this solution is that it assumes that number, represented as an integer, is 9 digits (can't start with a 0). If the number can start with a 0, then it has to be represented as a string (or converted to a string and padding with zeros). The logic to test will remain mostly intact, but the parts that assume integers will need to be swapped out with strings, and then you'll have to do parsing.
The specification you were given makes things a bit more complicated than they need to be: it's actually equivalent and simpler to just add the last digit into the checksum and make sure the checksum's last digit is 0.
The usual trouble new programmers have is "how do I get each digit?" Here's how:
In integer types, % 10 will delete everything but the last digit of the number: 123 % 10 == 3, and / 10 will delete the last digit of the number: 123 / 10 == 12.
In strings, str[i] - '0' will give you the digit at index i. The characters for digits are stored as special numbers: '0' is stored as 48 and '9' is stored as 57. If you subtract 48, you'll have the actual digit as a number. You don't really need to memorize "subtract 48", of course: if you just subtract '0', it will do the same thing: '8' - '0' == 8
Here are two efficient methods. One takes an int and checks the checksum of the SIN. One takes a string and checks both the format (must be "ddd ddd ddd") and the checksum of the SIN; though it's pretty efficient, it is a bit ugly and repetitive.
// Checks that the given int is a valid Canadian Social Insurance Number
// according to both range (000 000 000 to 999 999 998) and checksum.
public static bool IsValidSIN(int sin) {
if (sin < 0 || sin > 999999998) return false;
int checksum = 0;
for (int i = 4; i != 0; i--) {
checksum += sin % 10;
sin /= 10;
int addend = 2*(sin % 10); if (addend >= 10) addend -= 9;
checksum += addend;
sin /= 10;
}
return (checksum + sin) % 10 == 0;
}
// Checks that the given string is a valid Canadian Social Insurance Number
// according to both format ("ddd ddd ddd") and checksum.
// Implementation note: uses an admittedly ugly and repetitive parser.
public static bool IsValidSIN(string sin) {
if (sin.Length != 11) return false;
int checksum, addend;
checksum = sin[0] - '0';
if (checksum < 0 || checksum > 9) return false;
addend = 2*(sin[1] - '0'); if (addend >= 10) addend -= 9;
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = sin[2] - '0';
if (addend < 0 || addend > 9) return false;
checksum += addend;
if (sin[3] != ' ') return false;
addend = 2*(sin[4] - '0'); if (addend >= 10) addend -= 9;
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = sin[5] - '0';
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = 2*(sin[6] - '0'); if (addend >= 10) addend -= 9;
if (addend < 0 || addend > 9) return false;
checksum += addend;
if (sin[7] != ' ') return false;
addend = sin[8] - '0';
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = 2*(sin[9] - '0'); if (addend >= 10) addend -= 9;
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = sin[10] - '0';
if (addend < 0 || addend > 9) return false;
return (checksum + addend) % 10 == 0;
}
I don't know C# but here is a solution in Python. Maybe you can learn from it the method of how to implement it in C#.
def check(SIN):
SIN = ''.join(SIN.split(' '))
if len(SIN) != 9:
raise ValueError("A Canadian SIN must be 9 digits long")
check_digit = int(SIN[-1])
even_digits = [int(SIN[i]) for i in range(1,8,2)]
odd_digits = [int(SIN[i]) for i in range(0,8,2)]
total = sum(i/10 + i%10 for i in map(lambda x: 2*x, even_digits)) + sum(odd_digits)
if total%10 == 0:
return check_digit == 0
else:
return ((total/10)+1)*10 - total == check_digit
if __name__ == '__main__':
for SIN in ['123 456 782',
'123 456 789',
'046 454 286']:
print '%s is %sa valid Canadian SIN' % (SIN, '' if check(SIN) else 'NOT ')
which outputs:
123 456 782 is a valid Canadian SIN
123 456 789 is NOT a valid Canadian SIN
046 454 286 is a valid Canadian SIN
Search on the internet for "Luhn algorithm". You'll find a lot of examples.
The crux of the program is that you need to have some way of iterating over each integer in the SIN.
Since the easiest way is to convert the integer to a string for manipulation operations and back to an integer for addition/multiplication operations, I used the following approach:
The Program:
public class Program
{
static void Main(string[] args)
{
int sn = 123456782;
int[] Digits;
int AddedResult = 0;
string s = sn.ToString();
string sa = s.Substring(s.Length - 1, 1);
int checkDigit = Convert.ToInt32(sn.ToString().Substring(s.Length - 1, 1));
//get the last digit.
if (IsValidLength(sn))
{
sn = RemoveLastDigit(sn);
Digits = ExtractEvenDigits(sn);
Digits = DoubleDigits(Digits);
AddedResult = AddedEvenDigits(Digits);
AddedResult += AddOddDigits(sn);
if (IsValidSN(AddedResult, checkDigit))
{
Console.WriteLine("The number is valid");
}
else
{
Console.WriteLine("The Number is not valid");
}
}
else
{
Console.WriteLine("NotValidLength");
}
Console.Read();
}
public static bool IsValidSN(int AddedResult, int checkDigit)
{
return ((AddedResult % 10 == 0 && checkDigit == 0) || IsValidDifference(AddedResult, checkDigit));
}
public static bool IsValidDifference(int AddedResult, int checkDigit)
{
int nextHighestTens = AddedResult;
while (nextHighestTens % 10 != 0)
{
nextHighestTens++;
}
return ((nextHighestTens - AddedResult) == checkDigit);
}
public static int AddOddDigits(int sn)
{
string s = sn.ToString();
int i = 1;
int addedResult = 0;
foreach (char c in s)
{
if (i % 2 != 0)
{
addedResult += Convert.ToInt32(c.ToString());
}
i++;
}
return addedResult;
}
public static int AddedEvenDigits(int[] Digits)
{
int addedEvenDigits = 0;
string s = "";
for (int i = 0; i < Digits.Length; i++) //extract each digit. For example 12 is extracted as 1 and 2
{
s += Digits[i].ToString();
}
for (int i = 0; i < s.Length; i++) //now add all extracted digits
{
addedEvenDigits += Convert.ToInt32(s[i].ToString());
}
return addedEvenDigits;
}
public static int[] DoubleDigits(int[] Digits)
{
int[] doubledDigits = new int[Digits.Count()];
for (int i = 0; i < Digits.Length; i++)
{
doubledDigits[i] = Digits[i] * 2;
}
return doubledDigits;
}
public static int[] ExtractEvenDigits(int sn)
{
int[] EvenDigits = new int[4];
string s = sn.ToString(); //12345678
int j = 0;
for (int i = 1; i < s.Length; i += 2)
{
EvenDigits[j] = Convert.ToInt32(s[i].ToString());
j++;
}
return EvenDigits;
}
public static int RemoveLastDigit(int sn)
{
string s = sn.ToString();
return Convert.ToInt32(s.Substring(0, s.Count() - 1));
}
public static bool IsValidLength(int sn)
{
return (sn > 9999999 && sn < 1000000000);
}
}
I wrote this in about 20 minutes, so it's not really worthy to turn in. I plan on improving it as an exercise, and I wrote some unit tests for it (that I plan on making better).
[TestFixture]
public class SINTests
{
private int SinNumber = 123456782;
[Test]
public void TestValidNumber()
{
Assert.IsTrue(Program.IsValidLength(SinNumber));
}
[Test]
public void TestRemoveLastDigit()
{
Assert.AreEqual(12345678, Program.RemoveLastDigit(SinNumber));
}
[Test]
public void TestExtractEvenDigit()
{
int sn = 12345678;
int[] array = new int[] { 2,4,6,8 };
Assert.AreEqual(array, Program.ExtractEvenDigits(sn));
}
[Test]
public void TestAddOddDigits()
{
int sn = 12345678;
int result = 1 + 3 + 5 + 7;
Assert.AreEqual(result, Program.AddOddDigits(sn));
}
[Test]
public void TestDoubleEvenDigits()
{
int sn = 12345678;
int[] original = new int[] { 2, 4, 6, 8 };
int[] array = new int[] { 4, 8, 12, 16 };
Assert.AreEqual(array, Program.DoubleDigits(original));
}
[Test]
public void TestOddDigits()
{
int sn = 12345678;
Assert.AreEqual(16, Program.AddOddDigits(sn));
}
}
Since a string can be construed as an Array of Characters1, the operations that work on a string also need to be aware of the fact that Converting a character to an integer is different than converting a string to an integer. For instance:
Char c = '2';
int cInt = Convert.ToInt32(c); // returns 50
string s = c.ToString();
int sInt = Convert.ToInt32(s) //returns 2;
1Technically, a string is not an array of Characters in C# (though it is in C and C++), but because you can access the components of a string through an indexer, it can be treated like an array of characters.
I also recently coded this into an application. Before calling this, the string sSIN has already been checked through regex for being a 9-digit number.
public static bool IsCanadianSocialInsuranceNumber(string sSIN)
{
int iChecksum = 0;
int iDigit = 0;
for (int i = 0; i < sSIN.Length; i++)
{
// even number else odd
if (((i+1) % 2) == 0)
{
iDigit = int.Parse(sSIN.Substring(i, 1))*2;
iChecksum += (iDigit < 10) ? iDigit : iDigit - 9;
}
else
{
iChecksum += int.Parse(sSIN.Substring(i, 1));
}
}
return ((iChecksum % 10) == 0) ? true : false;
}
Here's a very simple way:
int test = 123456782;
if(test > 100000000 && test < 999999999)
{
int check = test % 10;
string temp = "";
foreach(char c in test.ToString().Substring(0, 8))
{
//The character codes for digits follow the same odd/even pattern as the digits.
//This code puts each digit or its value times 2, into a string and sums the digits
//after instead of keeping 2 separate totals
if(c % 2 == 1)
{
temp += c;
}
else
{
temp += (int.Parse(c.ToString()) * 2).ToString();
}
}
int temp2 = temp.Sum((x => int.Parse(x.ToString())));
//no need to compare the sum to the next 10, the modulus of 10 will work for this
int temp2mod = temp2 % 10;
if((temp2mod == 0 && temp2mod == check) || (10 - temp2mod == check))
return true;
}
return false;
public bool ValidateSIN(string sin)
{
if ((int)Char.GetNumericValue(sin[0]) == 0)
{
return false;
}
else
{
string evenString = "";
int totalOfEvens = 0;
int totalOfOdds = 0;
int total, nextMultipleOfTen, remainder;
int checkDigit = (int)Char.GetNumericValue(sin[8]);
// multiply each even number of the input string by 2
// get the resulting numbers into a string so the chars
// can be manipulated as individual digits
for (int i = 1; i <= 7; i += 2)
{
evenString += (Char.GetNumericValue(sin[i]) * 2);
}
// add the individual digits of the products from the above loop
foreach (char c in evenString)
{
totalOfEvens += (int)Char.GetNumericValue(c);
}
// get the odd numbers of the input string, minus the last number,
// and add them together
for (int i = 0; i <= 6; i += 2)
{
totalOfOdds += (int)Char.GetNumericValue(sin[i]);
}
total = totalOfEvens + totalOfOdds;
// take the quotient of total divided by 10 and add 1 to get the next multiple of ten
nextMultipleOfTen = (Math.DivRem(total, 10, out remainder) + 1) * 10;
if ((total % 10 == 0 && checkDigit == 0) || (checkDigit == nextMultipleOfTen - total))
{
return true;
}
else
{
return false;
}
}
}
Fastest method I've tried so far. No LINQ, no if/else, no odd/even checks, only 1 loop to get an array of integers from the string.
Caveat: no guards - input is assumed to be a string of 9 numbers.
public static bool IsValidSin(string input)
{
int[] luhnMap = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 };
int[] ints = new int[9];
for (int i = 0; i < 9; i++)
{
ints[i] = int.Parse(input[i].ToString());
}
int check = ints[0] + luhnMap[ints[1]] + ints[2] + luhnMap[ints[3]] + ints[4] + luhnMap[ints[5]] + ints[6] + luhnMap[ints[7]] + ints[8];
return (check % 10) == 0;
}

Mod of negative number is melting my brain

I'm trying to mod an integer to get an array position so that it will loop round. Doing i %
arrayLength works fine for positive numbers but for negative numbers it all goes wrong.
4 % 3 == 1
3 % 3 == 0
2 % 3 == 2
1 % 3 == 1
0 % 3 == 0
-1 % 3 == -1
-2 % 3 == -2
-3 % 3 == 0
-4 % 3 == -1
so i need an implementation of
int GetArrayIndex(int i, int arrayLength)
such that
GetArrayIndex( 4, 3) == 1
GetArrayIndex( 3, 3) == 0
GetArrayIndex( 2, 3) == 2
GetArrayIndex( 1, 3) == 1
GetArrayIndex( 0, 3) == 0
GetArrayIndex(-1, 3) == 2
GetArrayIndex(-2, 3) == 1
GetArrayIndex(-3, 3) == 0
GetArrayIndex(-4, 3) == 2
I've done this before but for some reason it's melting my brain today :(
I always use my own mod function, defined as
int mod(int x, int m) {
return (x%m + m)%m;
}
Of course, if you're bothered about having two calls to the modulus operation, you could write it as
int mod(int x, int m) {
int r = x%m;
return r<0 ? r+m : r;
}
or variants thereof.
The reason it works is that "x%m" is always in the range [-m+1, m-1]. So if at all it is negative, adding m to it will put it in the positive range without changing its value modulo m.
Please note that C# and C++'s % operator is actually NOT a modulo, it's remainder. The formula for modulo that you want, in your case, is:
float nfmod(float a,float b)
{
return a - b * floor(a / b);
}
You have to recode this in C# (or C++) but this is the way you get modulo and not a remainder.
Single-line implementation using % only once:
int mod(int k, int n) { return ((k %= n) < 0) ? k+n : k; }
Comparing top two answers
(x%m + m)%m;
and
int r = x%m;
return r<0 ? r+m : r;
Nobody actually mentioned the fact that the first one may throw an OverflowException while the second one won't. Even worse, with default unchecked context, the first answer may return the wrong answer (see mod(int.MaxValue - 1, int.MaxValue) for example). So the second answer not only seems to be faster, but also more correct.
ShreevatsaR's answer won't work for all cases, even if you add "if(m<0) m=-m;", if you account for negative dividends/divisors.
For example, -12 mod -10 will be 8, and it should be -2.
The following implementation will work for both positive and negative dividends / divisors and complies with other implementations (namely, Java, Python, Ruby, Scala, Scheme, Javascript and Google's Calculator):
internal static class IntExtensions
{
internal static int Mod(this int a, int n)
{
if (n == 0)
throw new ArgumentOutOfRangeException("n", "(a mod 0) is undefined.");
//puts a in the [-n+1, n-1] range using the remainder operator
int remainder = a%n;
//if the remainder is less than zero, add n to put it in the [0, n-1] range if n is positive
//if the remainder is greater than zero, add n to put it in the [n-1, 0] range if n is negative
if ((n > 0 && remainder < 0) ||
(n < 0 && remainder > 0))
return remainder + n;
return remainder;
}
}
Test suite using xUnit:
[Theory]
[PropertyData("GetTestData")]
public void Mod_ReturnsCorrectModulo(int dividend, int divisor, int expectedMod)
{
Assert.Equal(expectedMod, dividend.Mod(divisor));
}
[Fact]
public void Mod_ThrowsException_IfDivisorIsZero()
{
Assert.Throws<ArgumentOutOfRangeException>(() => 1.Mod(0));
}
public static IEnumerable<object[]> GetTestData
{
get
{
yield return new object[] {1, 1, 0};
yield return new object[] {0, 1, 0};
yield return new object[] {2, 10, 2};
yield return new object[] {12, 10, 2};
yield return new object[] {22, 10, 2};
yield return new object[] {-2, 10, 8};
yield return new object[] {-12, 10, 8};
yield return new object[] {-22, 10, 8};
yield return new object[] { 2, -10, -8 };
yield return new object[] { 12, -10, -8 };
yield return new object[] { 22, -10, -8 };
yield return new object[] { -2, -10, -2 };
yield return new object[] { -12, -10, -2 };
yield return new object[] { -22, -10, -2 };
}
}
I like the trick presented by Peter N Lewis on this thread: "If n has a limited range, then you can get the result you want simply by adding a known constant multiple of [the divisor] that is greater that the absolute value of the minimum."
So if I have a value d that is in degrees and I want to take
d % 180f
and I want to avoid the problems if d is negative, then instead I just do this:
(d + 720f) % 180f
This assumes that although d may be negative, it is known that it will never be more negative than -720.
Just add your modulus (arrayLength) to the negative result of % and you'll be fine.
You're expecting a behaviour that is contrary to the documented behaviour of the % operator in c# - possibly because you're expecting it to work in a way that it works in another language you are more used to. The documentation on c# states (emphasis mine):
For the operands of integer types, the result of a % b is the value produced by a - (a / b) * b. The sign of the non-zero remainder is the same as that of the left-hand operand
The value you want can be calculated with one extra step:
int GetArrayIndex(int i, int arrayLength){
int mod = i % arrayLength;
return (mod>=0) : mod ? mod + arrayLength;
}
For the more performance aware devs
uint wrap(int k, int n) ((uint)k)%n
A small performance comparison
Modulo: 00:00:07.2661827 ((n%x)+x)%x)
Cast: 00:00:03.2202334 ((uint)k)%n
If: 00:00:13.5378989 ((k %= n) < 0) ? k+n : k
As for performance cost of cast to uint have a look here
Adding some understanding.
By Euclidean definition the mod result must be always positive.
Ex:
int n = 5;
int x = -3;
int mod(int n, int x)
{
return ((n%x)+x)%x;
}
Output:
-1
All of the answers here work great if your divisor is positive, but it's not quite complete. Here is my implementation which always returns on a range of [0, b), such that the sign of the output is the same as the sign of the divisor, allowing for negative divisors as the endpoint for the output range.
PosMod(5, 3) returns 2
PosMod(-5, 3) returns 1
PosMod(5, -3) returns -1
PosMod(-5, -3) returns -2
/// <summary>
/// Performs a canonical Modulus operation, where the output is on the range [0, b).
/// </summary>
public static real_t PosMod(real_t a, real_t b)
{
real_t c = a % b;
if ((c < 0 && b > 0) || (c > 0 && b < 0))
{
c += b;
}
return c;
}
(where real_t can be any number type)
A single line implementation of dcastro's answer (the most compliant with other languages):
int Mod(int a, int n)
{
return (((a %= n) < 0) && n > 0) || (a > 0 && n < 0) ? a + n : a;
}
If you'd like to keep the use of % operator (you can't overload native operators in C#):
public class IntM
{
private int _value;
private IntM(int value)
{
_value = value;
}
private static int Mod(int a, int n)
{
return (((a %= n) < 0) && n > 0) || (a > 0 && n < 0) ? a + n : a;
}
public static implicit operator int(IntM i) => i._value;
public static implicit operator IntM(int i) => new IntM(i);
public static int operator %(IntM a, int n) => Mod(a, n);
public static int operator %(int a, IntM n) => Mod(a, n);
}
Use case, both works:
int r = (IntM)a % n;
// Or
int r = a % n(IntM);
Here's my one liner for positive integers, based on this answer:
usage:
(-7).Mod(3); // returns 2
implementation:
static int Mod(this int a, int n) => (((a %= n) < 0) ? n : 0) + a;
There are many implementations of the mod function, and I think it's worth it to list all of them --- at least according to Wikipedia, I'm sure there are more.
// Important to be able to use `MathF`.
using System;
public static class MathFUtils {
public static class Mod {
public static float Trunc(float a, float b) =>
a - b * ((int)(a / b));
public static float Round(float a, float b) =>
a - b * MathF.Round(a / b);
public static float Floor(float a, float b) =>
a - b * MathF.Floor(a / b);
public static float Ceil(float a, float b) =>
a - b * MathF.Ceiling(a / b);
public static float Euclidean(float a, float b) =>
a - MathF.Abs(b) * MathF.Floor(a / MathF.Abs(b));
}
}
According to the Wikipedia (as well as my experience) stick to Euclidean. It is the most useful in terms of mathematical and probabilistic properties. If you ever need Trunc, then I believe % does just that.
Also, for those of you who might be confused as to what each of them do, and how, I highly recommend reading the Wikipedia article (even if it's hard) and looking at the images of each representation.
Of course these are not necessarily the most performant, but they do work. If you are concerned about performance, I recommend finding a local C# god, or asking one as they pass through our mortal plane.
ShreevatsaR's second answer:
int mod(int x, int m) {
int r = x % m;
return r < 0 ? r + m : r;
}
can be written using the var pattern and switch expressions in newer versions of C# as a one-liner:
int mod(int x, int m) => (x % m) switch
{
< 0 and var r => r + m, var r => r
}

Solving brain teaser using linq

At the very outset let me express my sincere thanks to Marc Gravel,Dahlbyk and the rest for helping me to apply linq practically.
The following are few questions which I have faced in an interview to solve applying Linq. As I am not familiar with Linq I solved it without using Linq.
I appreciate the answers which helps me to solve them using Linq
Thanks in advance.
Question 1:
The Problem is to find different digits such that,in whatever order they are used to make a three-digit number,that number will not be divisible by:
3,5,7,11,13 or 17.
To ensure that there is no ambuigity,suppose the three digits
are a,b,and c.Then,none of the combination of the numbers:
say abc,acb,bac,bca,cab and cba will divide by 3,5,7,11,13 or 17.
Example :
When I take 248 none of its combination(284,428,482,842,824) will exactly divisible by 3,5,7,11,13 or 17.
public void FindingRareNumbers()
{
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
for (int k = 1; k <= 9; k++)
{
//to form the three digit
string digit = i.ToString() + j.ToString() + k.ToString();
//converting to integer
int StrToDigit = Convert.ToInt32(digit);
char[] digitcombination = digit.ToCharArray();
string PossibleCombination = "";
bool testpassed = false;
int dcount = 0;
#region different possible combinations
for (int p = 0; p <= 2; p++)
{
for (int q = 0; q <= 2; q++)
{
for (int r = 0; r <= 2; r++)
{
// The following condition avoid the repeatance
// of digit like 111,111,111
if (p != q && p != r && r != q)
{
PossibleCombination =
digitcombination[p].ToString() +
digitcombination[q].ToString() +
digitcombination[r].ToString();
int num = Convert.ToInt32(PossibleCombination);
if (num % 3 != 0 && num % 5 != 0 && num % 7 != 0
&& num % 11 != 0 && num % 11 != 0
&& num % 13 != 0 && num % 17 != 0)
{
//count is increment for 6 times
// it satisfies the condition
dcount++;
testpassed = true;
}
}
}
}
}
#endregion combination
if (testpassed && dcount==6)
{
Console.WriteLine(StrToDigit);
}
}
}
}
}
(coding is working)
Question 2:
The task is to arrange the element in matrix so that all rows,columns,and diagonals add up to the same total.(Bit problem in coding ,I am trying to solve it).
------------------
1 2 3
-----------------
4 5 6
-----------------
7 8 9
-----------------
example :
The one of solutions is as follows:
-----------
2 9 4
-----------
7 5 3
----------
6 1 8
----------
I agree that Marc's solution to your first problem is a reasonable approach. But I think there's a larger question here, which is "how do I solve problems like this in a LINQ-ish manner?"
Notice how your solution is completely "procedural" and "imperative". Your code specifies a series of steps that you would execute, one after the other, with deep loops. Each step along the way is meaningless unless you understand its place in the larger whole.
There are two ideas I like to use when solving problems with LINQ:
Describe what the program is doing logically, rather than listing a series of commands
Characterize the problem as a query against a data set rather than as a procedure to follow.
So, what's our data set? We wish to filter out some elements from the set of all combinations of three digits.
How do we filter them? Permute the digits and then perform a divisibility check on each permutation.
OK, so now we have a structure for our program:
var query = from c in ThreeDigitCombinations()
where DivisibilityCheckPasses(c)
select c;
foreach(Combination result in query) Console.WriteLine(result);
And now you can continue breaking down each of those further, solving each sub-problem using LINQ in turn.
Same goes for your "magic square" problem; you're looking for a permutation that has a certain property, so write a generator of permutations, write a filter, and execute it.
For the first:
static IEnumerable<int> Permute(int x, int y, int z)
{
yield return x * 100 + y * 10 + z;
yield return x * 100 + z * 10 + y;
yield return y * 100 + x * 10 + z;
yield return y * 100 + z * 10 + x;
yield return z * 100 + x * 10 + y;
yield return z * 100 + y * 10 + x;
}
static void Main()
{
var divs = new[] {3,5,7,11,13,17};
// combinations of 1-9
var combinations =
from x in Enumerable.Range(1, 7)
from y in Enumerable.Range(x + 1, 8 - x)
from z in Enumerable.Range(y + 1, 9 - y)
select new { x, y, z };
// permute
var qry = from comb in combinations
where !Permute(comb.x, comb.y, comb.z).Any(
i => divs.Any(d => i % d == 0))
select comb;
foreach (var answer in qry)
{
Console.WriteLine("{0}, {1}, {2}", answer.x, answer.y, answer.z);
}
}
For the second - not elegant, but it works (returns the 8 permutations of the sample):
static void Main() {
var data = Enumerable.Range(1, 9);
var magicSquares =
// generate 1st row and deduce the target
from a in data let arrA = new[] { a }
from b in data.Except(arrA) let arrB = new[] { a,b }
from c in data.Except(arrB) let arrC = new[] { a,b,c }
let target = a + b + c
// generate 2nd row and filter to target matches
from d in data.Except(arrC) let arrD = new[] { a,b,c,d }
from e in data.Except(arrD) let arrE = new[] { a,b,c,d,e }
from f in data.Except(arrE) let arrF = new[] { a,b,c,d,e,f }
where d + e + f == target
// generate 3rd row and filter to target matches
from g in data.Except(arrF) let arrG = new[] { a,b,c,d,e,f,g }
from h in data.Except(arrG) let arrH = new[] { a,b,c,d,e,f,g,h }
from i in data.Except(arrH)
where g + h + i == target
// filter columns
&& a + d + g == target
&& b + e + h == target
&& c + f + i == target
// filter diagonals
&& a + e + i == target
&& c + e + g == target
select new {a,b,c,d,e,f,g,h,i};
foreach (var row in magicSquares)
{
Console.WriteLine("{0} {1} {2}", row.a, row.b, row.c);
Console.WriteLine("{0} {1} {2}", row.d, row.e, row.f);
Console.WriteLine("{0} {1} {2}", row.g, row.h, row.i);
Console.WriteLine();
}
}

Categories