Find/simplify overlapping modulo - c#

I have some code solving today's "Advent of code part 2". https://adventofcode.com/
I have currently many hardcoded modulo conditions, is there any simple way to reduce the number of conditions?
Since in general you can skip checking x % 4 == 0 if you already checked x % 2 == 0. But I have a hard time figuring out how to simplify when there is addition involved. Any suggestions or resources I can look up?
if (delay % 6 == 0)
{
return false;
}
if ((delay +1) % 2 == 0)
{
return false;
}
if ((delay +2) % 4 == 0)
{
return false;
}
if ((delay + 4) % 6 == 0)
{
return false;
}
if ((delay + 6) % 14 == 0)
{
return false;
}
if ((delay + 8) % 8 == 0)
{
return false;
}
if ((delay + 10) % 14 == 0)
{
return false;
}
if ((delay + 12) % 10 == 0)
{
return false;
}
if ((delay + 14) % 10 == 0)
{
return false;
}
if ((delay + 16) % 14 == 0)
{
return false;
}
if ((delay + 18) % 10 == 0)
{
return false;
}
if ((delay + 20) % 10 == 0)
{
return false;
}
if ((delay + 22) % 22 == 0)
{
return false;
}
if ((delay + 24) % 22 == 0)
{
return false;
}
if ((delay + 26) % 18 == 0)
{
return false;
}
if ((delay + 28) % 14 == 0)
{
return false;
}
if ((delay + 32) % 14 == 0)
{
return false;
}
if ((delay + 36) % 16 == 0)
{
return false;
}
if ((delay + 40) % 14 == 0)
{
return false;
}
if ((delay + 44) % 32 == 0)
{
return false;
}
if ((delay + 50) % 18 == 0)
{
return false;
}
if ((delay + 56) % 26 == 0)
{
return false;
}
if ((delay + 58) % 26 == 0)
{
return false;
}
if ((delay + 60) % 26 == 0)
{
return false;
}
if ((delay + 62) % 22 == 0)
{
return false;
}
if ((delay + 64) % 26 == 0)
{
return false;
}
if ((delay + 66) % 26 == 0)
{
return false;
}
if ((delay + 68) % 26 == 0)
{
return false;
}
if ((delay + 70) % 26 == 0)
{
return false;
}
if ((delay + 74) % 26 == 0)
{
return false;
}
if ((delay + 76) % 26 == 0)
{
return false;
}
if ((delay + 80) % 26 == 0)
{
return false;
}
if ((delay + 88) % 26 == 0)
{
return false;
}
doSomeComputation...

I am assuming that delay is always nonnegative. If that is not guaranteed by your inputs, you can replace the modulus call with a version that fixes it, as in this answer. That said, the logic you posted could be replicated with this:
const int lcm = 1441440;
int[] residues = new int[]
{
1924,
92644,
132964,
223684,
354724,
395044,
616804,
657124,
788164,
878884,
1009924,
1050244,
1181284,
1272004,
1312324,
1403044
};
if (!residues.Contains(delay % lcm)) return false;
Explanation of how to generate it: lcm is the least common multiple of the numbers you are modding by. You can get that by asking WolframAlpha or any number of other ways. The constant residues can be obtained by simply iterating over all the residues mod lcm and checking which ones pass the logic as you have it written already. The following code is what I used to print them out, where the function myPass is just the logic that you provided above.
for (int i = 0; i < 1441440; ++i)
if (myPass(i))
Console.WriteLine("i = {0}", i);
Explanation of why it works: If delay is an integer and m is a positive integer and n is a positive integer that is divisible by m, then the value of delay % m is equal to (delay % n) % m. An example: suppose an integer delay has delay % lcm == 1924. Then we have that delay % 6 is equal to (delay % lcm) % 6 which is 1924 % 6 which is 4. Similarly, as long as delay % lcm is a value i in the hard-coded list of residues which we tested to match all of the various conditions in your ifs, then we know that delay matches them, too, because--for whatever m a particular if was testing against--we generated our list in such a way that we already know that i % m matches the condition, and now we have that (delay % m) == (delay % lcm) % m) == i % m.
Note: this approach is only feasible because your set of conditions excludes many residues of only small moduli. If there were, for example, one outlying condition comparing against a large prime, the list of residues could easily become too large to handle.

Related

Write method that checks if a given number (positive integer) contains digit 3. If it is true answer is true.if it is false answer is false.in C#

Do not convert number to other type. Do not use built-in functions like Contains(), StartsWith(), etc.
while (number > 0)
{
if (number % 10 == 3)
{
return true;
}
number /= 10;
}
return false;`
Method that checks if given number (positive integer) contains digit 3
You were nearly there
private static bool HasDigit(int num,int digit)
{
while (num > 0)
{
if(num % 10 == digit)
return true;
num /= 10;
}
return false;
}
Usage
Console.WriteLine(HasDigit(1222, 3));
Console.WriteLine(HasDigit(23345, 3));
Output
False
True
Other approaches might be
private static bool HasDigit2(int num, int digit)
{
var str = num.ToString();
for (int i = 0; i < str.Length; i++)
if (str[i] == ((char) digit) + '0')
return true;
return false;
}
Or
private static bool HasDigit3(int num, int digit)
=> num.ToString().Any(t => t == ((char) digit) + '0');
Here's a recursive solution:
public static bool Contains3(int n) {
if (n < 10) {
if (n == 3) {
return true;
} else {
return false;
}
}
return n % 10 == 3 || Contains3(n / 10);
}

Stack overflow with a loop c#

I am currently having problems with this loop. It becomes an infinite loop and i get a stack overflow error. This is for a interest rate trade swap application. i is the length of the trade and l is the increasing index.
private void button1_Click(object sender, EventArgs e)
{
int outp = 0;
int i = int.Parse(tradeLength.Text);
string month = "January";
for (int l = 1; l <= i; l++)
{
Console.WriteLine("I iterated " + l + " Amount of times");
if (l == 1)
{
month = "January";
}
if (l == 2)
{
month = "February";
}
if (l == 3)
{
month = "March";
}
if (l == 4)
{
month = "Aprll";
}
if (l == 5)
{
month = "May";
}
if (l == 6)
{
month = "June";
}
if (l == 7)
{
month = "July";
}
if (l == 8)
{
month = "August";
}
if (l == 9)
{
month = "September";
}
if (l == 10)
{
month = "October";
}
if (l == 11)
{
month = "November";
}
if (l == 12)
{
month = "December";
}
else
{
month = "Null";
l = 1;
}
The cause is the final else:
if (l == 12) {
month = "December";
}
else { // <- if l != 12 (e.g. l == 1) restart the loop
month = "Null";
l = 1;
}
you want else if:
if (l == 1)
{
month = "January";
}
else if (l == 2)
{
...
}
...
else if (l == 12)
{
...
}
else {
month = "Null";
l = 1;
}
Edit: Another problem (see FKEinternet's comment) is a user input: if i is greater than 12 l never reaches it. You have to either validate the user input:
int i = int.Parse(tradeLength.Text);
if (i > 12)
i = 12; // or ask for other value
or use modular arithmetics:
for (int index = 1; index <= i; index++) {
int l = index % 12 + 1;
if (l == 1)
{
month = "January";
}
else if (l == 2)
...
else if (l == 12)
...
else
{
month = "Null";
l = 1;
}
}
It is not a very good idea to set the loop variable inside the loop. Like #stuartd pointed out, in your else line you set the loop variable to 1 and causing the loop to start all over again. Remove the l=1 line in your else block.
I presume you want to go to next year when i > 12. The way your code is made, when this happens, you get to loop forever, because "l" never reaches a number bigger than 12, it becomes 1 when it hits 13 and starts over.
To fix this, instead of
if (l == 1)
you want to use
if ((l % 12) == 1)
so your entire loop would be like this:
for (int l = 1; l <= i; l++)
{
Console.WriteLine("I iterated " + l + " Amount of times");
if ((l % 12) == 1)
{
month = "January";
}
if ((l % 12) == 2)
{
month = "February";
}
if ((l % 12) == 3)
{
month = "March";
}
if ((l % 12) == 4)
{
month = "Aprll";
}
if ((l % 12) == 5)
{
month = "May";
}
if ((l % 12) == 6)
{
month = "June";
}
if ((l % 12) == 7)
{
month = "July";
}
if ((l % 12) == 8)
{
month = "August";
}
if ((l % 12) == 9)
{
month = "September";
}
if ((l % 12) == 10)
{
month = "October";
}
if ((l % 12) == 11)
{
month = "November";
}
if ((l % 12) == 0)
{
month = "December";
}
{
PS = this is really not the right way to do this, I'm just using your own code and making the least amount of mods for it to work as intented. Good luck!

10001st Prime - Project Euler [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
So I'm doing the 7th Project Euler problem, and I'm not sure why this code isn't working, it seems to be okay so small numbers, I've tested 1-10 and it's fine, but doesn't return the correct answer at 10001 - returns 104745.
And yes, I know it's inefficient.
private void eulerSeven(int num)
{
// Start the Prime count at 3, with 2 already counted.
int primecount = 1, counter = 3;
//While num of primes counted < the nth prime
while (primecount < num)
{
bool isPrime = true;
//check every number from 2 -> the current number we're checking
for (int i = 2; i < counter; i++)
{
if (counter%i == 0)
{
//if divisible, not a prime
isPrime = false;
break;
}
}
if (isPrime) //If is a prime, increment counter
{ primecount++; }
// Go to next number (only checking odds)
counter += 2;
}
//output nth prime
Console.WriteLine(counter);
}
As stated by #lanorkin, the problem was:
should be counter - 2
but also, I would like to suggest a look at https://codereview.stackexchange.com/questions/124644/project-euler-7-10001st-prime, so this code should do the same, but very very fast (5ms on my machine):
static void Main(string[] args)
{
var stopwatch = Stopwatch.StartNew();
Console.WriteLine(CalculateEulerSeven(10001)); // should be 104745
stopwatch.Stop();
Console.WriteLine("Time to calculate in milliseconds : {0}", stopwatch.ElapsedMilliseconds);
Console.ReadKey();
}
private static int CalculateEulerSeven(int num)
{
int primecount = 1, counter = 3;
while (primecount < num)
{
bool isPrime = IsPrime(counter);
if (isPrime) primecount++;
counter += 2;
}
return counter;
}
static bool IsPrime(int value)
{
if (value < 2) { return false; }
if (value % 2 == 0) { return value == 2; }
if (value % 3 == 0) { return value == 3; }
if (value % 5 == 0) { return value == 5; }
if (value == 7) { return true; }
for (int divisor = 7; divisor * divisor <= value; divisor += 30)
{
if (value % divisor == 0) { return false; }
if (value % (divisor + 4) == 0) { return false; }
if (value % (divisor + 6) == 0) { return false; }
if (value % (divisor + 10) == 0) { return false; }
if (value % (divisor + 12) == 0) { return false; }
if (value % (divisor + 16) == 0) { return false; }
if (value % (divisor + 22) == 0) { return false; }
if (value % (divisor + 24) == 0) { return false; }
}
return true;
}

Only assignment, call, decrement can be used

I'm trying to find integers in a certain range that are prime. I seem to be getting an error when I put a for loop in my else statement.
private static bool prime(int n,out int factor)
{
factor = 1;
if (n < 2)
return false;
else if (n == 2 || n == 3)
return true;
else if( n % 2 == 0)
return false;
for(int r = 3; r < (Math.Sqrt(n) + 1); r + 2)
{
if ((Convert.ToInt32(n)) % r == 0)
return false;
}
}
for(int r=3;r<(Math.Sqrt(n)+1);r+2)
r+2 creates a result, but it isn't assigned to anything. You want either r = r + 2 or r += 2
There are couple of problems with your code.
Firstly you can fix the assigment problem like
r=r+2
secondly, your function needs to return something from all code paths. Which it isn't doing at the moment. I have returned true at the end, though you can choose your logic here.
private static bool prime(int n, out int factor)
{
factor = 1;
if (n < 2)
return false;
else if (n == 2 || n == 3)
return true;
else if (n % 2 == 0)
{
return false;
}
for (int r = 3; r < (Math.Sqrt(n) + 1); r = r + 2)
{
if ((Convert.ToInt32(n)) % r == 0)
return false;
}
return true;
}

Modulus Visual Studio 2013

I was just wondering how I could state if x + y + z % 2 == 0 BUT only do this statement IF the three values aren't set to 0. I require the values to be 0.
Example of my code & posStatus may hold variables of the value 0. The problem is when all three of them are 0 an issue occurs. The user and program over time fill in these values.
else if (posStatus[0] + posStatus[4] + posStatus[8] % 2 == 0)
{
if (posStatus[0] == 0)
{
posStatus[0] = 2;
return;
}
else if (posStatus[4] == 0)
{
posStatus[4] = 2;
return;
}
else if (posStatus[8] == 0)
{
posStatus[8] = 2;
return;
}
}
if((x!=0 && y!=0 && z!=0) && x + y + z % 2 == 0)
//do your stuff
Logical operators in C# are converted to series of if-else constructions during compilation, so if first condition is not true, other ones won't be checked.
if(posStatus[0] != 0 &&
posStatus[4] != 0 &&
posStatus[8] != 0 &&
(posStatus[0] + posStatus[4] + posStatus[8]) % 2 == 0)
{
// Do something
}
if((posStatus[0]!=0 && posStatus[4]!=0 && posStatus[8]!=0) &&
(posStatus[0] + posStatus[4] + posStatus[8]) % 2 == 0)
{
}

Categories