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)
{
}
Related
I'm using 3 iterators to iterate through an int[] object to find lists containing three int's that all sum to 0, without adding duplicate lists to the final return object. Once the iterators find a valid sequence, each array value that the iterator points to is added to a temporary IList object via syntax such as "tempList.Add(nums[a]);" e.t.c. This tempList is then added to the final IList<IList> return object.
To check for duplicates, I'm using the following sytax:
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Contains(tempList))
{
answerList.Add(tempList);
}
This works when the IList<IList> is initially empty, however the second clause evaluated "false" for the following scenario, which is preventing the valid tempList from being added to the IList<IList> answerList :
IList<IList<int>> == [[-1,0,1]]
tempList == [-1,-1,2]
Do I need to extend a Comparable interface to correct this? I've double checked the array values for a, b and c and they collectively sum to 0, so I'm certain that it's the .Contains comparison that is causing issue.
Here is the code:
public IList<IList<int>> ThreeSum(int[] nums) // maybe use three index pointers to fill triplet, one starting at index 0, one
// starting at index nums.Lenght - 1 and one starting near or at middle
// 5 billion possible combinations of triplets among array of 3001 triplets
{
IList<int> tempList = new List<int>();
IList<IList<int>> answerList = new List<IList<int>>();
int countPositive = 0;
int countNegative = 0;
bool addAnswerList = false;
int indexPositive = 0;
int a = 0;
int b = 0;
int c = 0;
bool aExtreme = false;
bool bExtreme = false;
bool cExtreme = false;
if (nums == null)
return answerList;
if (nums.Length == 0 /* || /* nums.Length < 3 */)
return answerList;
if (nums.Length == 1 && nums[0] == 0)
return answerList;
for (int i = 0; i < nums.Length; i++) // corner case where all array values are either postive or negative
// 0 sum triplet not possible
{
if (nums[i] > 0)
countPositive++;
else if (nums[i] < 0)
countNegative++;
}
if ((countPositive == nums.Length || countNegative == nums.Length) || (countNegative == 0 && countPositive == 0))
return answerList;
if (nums.Length < 51)
{
int temp = 0;
for (int i = 1; i < nums.Length; i++) // use recursive sort to go through 3001 elements, use linear if less than 51
{
temp = nums[i];
int j = i;
while (j > 0 && nums[j-1] > temp)
{
nums[j] = nums[j-1];
j--;
}
nums[j] = temp;
}
Console.WriteLine(String.Join(" ", nums));
}
else if (nums.Length > 50) // recursive sort for larger input array
{
mergeSort(nums);
}
// Now nums is storted, 0 sum triplet will most likely be found where entries change from negative to positive
for (int i = 0; i < nums.Length; i++)
{
if (nums[i] > 0)
{
// toPositive = true;
indexPositive = i;
break;
}
}
Console.WriteLine(indexPositive);
if (indexPositive == 0) // case to make sure accessors do not get invalid number
{
a = 0; // initialize other two index accessors in addition to indexPositive
b = 0;
}
else
{
a = indexPositive - 1; // initialize other two index accessors in addition to indexPositive
b = indexPositive - 1;
}
c = indexPositive; // store initial indexPositive value into variable c as indexPositive will change
// throughtout the interation
// if indexPositive is less than (nums.Length / 2), iterate two other accessors towards end of nums
// else, interate two other accessors towards nums[0]
if (c < (nums.Length / 2)) // use iterator c in place of indexPositive
{
while (c < nums.Length && b < nums.Length && a >= 0)
{
if (a == 0 || a == nums.Length - 3)
{
aExtreme = true;
}
else
{
aExtreme = false;
}
if (b == 1 || b == nums.Length - 2)
{
bExtreme = true;
}
else
{
bExtreme = false;
}
if (c == 2 || c == nums.Length - 1)
{
cExtreme = true;
}
else
{
cExtreme = false;
}
if ((c != a && c != b && a != b) && (nums[c] + nums[a] + nums[b] == 0)) // if nums add to 0, add them to tempList
{
tempList.Add(nums[a]);
tempList.Add(nums[b]);
tempList.Add(nums[c]);
}
// need to check if exact triplet is duplicate or if tempList triplet contains same 3 values in different order
// 3 values in different order not an issues since input list is already sorted!!!!
// but need to be aware order accessors are added to temp list. Accessors cannot "crossover" one another!!!
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Any(x => x.SequenceEqual(tempList)) /*!answerList.Contains(tempList)*/)
// Having issues, answerList.Contains does not currently do what is desired
{
answerList.Add(tempList); // add tempList to answerList
addAnswerList = true;
}
else
{
addAnswerList = false;
}
tempList.Clear(); // clear tempList to prepare for next entry
// Make changes here to make sure only 1 accessor iterates at a time, to check all possible and logical combinations
// Since array is now sorted, iteration towards sums[0] only has to continue if sum of 3 accessors is greater than 0
// Once active accessor returns a value that results in 0 sum, further iteration is guaranteed to return
// an identical triplet or one that sums to less than 0. At this point, the two accessors that are going in the same
// direction should be iterated by 1 position and the cycle repeated
if (nums[a] + nums[b] + nums[c] < 0) // still have chance to get to 0 value triplet with rightmost accessor
{
c++;
}
else if ((addAnswerList == true) || nums[a] + nums[b] + nums[c] > 0) // no point in further iteration,
// reset 'c' accessor to original starting
// position and decrement other accessors by 1
// towards first array element
{ // to begin cycle again
c = indexPositive - 1;
b--;
a--;
}
}
}
else // a and b accessors are interated towards 0
{
while (c < nums.Length && a >= 0 && b >= 0)
{
if (a == 0 || a == nums.Length - 3)
{
aExtreme = true;
}
else
{
aExtreme = false;
}
if (b == 1 || b == nums.Length - 2)
{
bExtreme = true;
}
else
{
bExtreme = false;
}
if (c == 2 || c == nums.Length - 1)
{
cExtreme = true;
}
else
{
cExtreme = false;
}
if ((c != a && c != b && a != b) && (nums[c] + nums[a] + nums[b] == 0)) // if nums add to 0, add them to tempList
// need to check if exact triplet is duplicate
{
tempList.Add(nums[a]);
tempList.Add(nums[b]);
tempList.Add(nums[c]);
}
Console.WriteLine(String.Join(" ", tempList));
// need to check if exact triplet is duplicate or if tempList triplet contains same 3 values in different order
// 3 values in different order not an issues since input list is already sorted!!!!
// but need to be aware order accessors are added to temp list. Accessors cannot "crossover" one another!!!
if ((nums[c] + nums[a] + nums[b] == 0) && !answerList.Any(x => x.SequenceEqual(tempList)))
// Having issues, answerList.Contains does not currently do what is desired
{
answerList.Add(tempList); // add tempList to answerList
addAnswerList=true;
}
else
{
addAnswerList = false;
}
tempList.Clear(); // clear tempList to prepare for next entry
// Make changes here to make sure only 1 accessor iterates at a time, to check all possible and logical combinations
// Since array is now sorted, iteration towards sums[0] only has to continue if sum of 3 accessors is greater than 0
// Once active accessor returns a value that results in 0 sum, further iteration is guaranteed to return
// an identical triplet or one that sums to less than 0. At this point, the two accessors that are going in the same
// direction should be iterated by 1 position and the cycle repeated
if (nums[a] + nums[b] + nums[c] > 0) // still have chance to get to 0 value triplet with
// leftmost accessor
{
a--;
}
else if ((addAnswerList == true) || nums[a] + nums[b] + nums[c] < 0) // no point in further iteration,
// reset 'a' accessor to original starting
// position and increment other accessors by 1
// towards last array element
{ // to begin cycle again
a = b; // a = indexPositive - 1;
if ((bExtreme == false && b < nums.Length - 2) && (cExtreme == false && c < nums.Length - 1))
// if there is still room to run towards end of array, increment, else decrement
{
b++;
c++;
}
else
{
bExtreme = true;
cExtreme = true;
a -= 2;
b--;
}
}
}
}
Console.WriteLine(String.Join(" ", answerList));
return answerList;
}
public void merge(int[] array1, int[] array2, int[] outArray)
{
int i = 0;
int j = 0;
while (i + j < outArray.Length)
{
if (j == array2.Length || (i < array1.Length && (array1[i] < array2[j])))
{
outArray[i + j] = array1[i++];
}
else
{
outArray[i + j] = array2[j++];
}
}
}
public void mergeSort(int[] inputArray)
{
if (inputArray.Length < 2)
return;
int[] firstHalf = new int[inputArray.Length / 2];
int[] secondHalf = new int[inputArray.Length / 2];
for (int i = 0; i < (inputArray.Length / 2); i++)
{
firstHalf[i] = inputArray[i];
}
for (int i = inputArray.Length / 2; i < inputArray.Length; i++)
{
secondHalf[i] = inputArray[i];
}
mergeSort(firstHalf);
mergeSort(secondHalf);
merge(firstHalf, secondHalf, inputArray);
}
You can replace
answerList.Contains(tempList))
which checks only for reference equality, with
answerList.Any(x => x.SequenceEqual(tempList))
which will run SequenceEqual on the answerList until it finds the first answer that has the same integer elements and returns false if none can be found.
Keep in mind that these functions require System.Linq.
Credit: thanks Hans Kesting for suggesting Any(...) over FirstOrDefault(...) != null
I am trying to complete this assignment where if an integer is divisible by 2,3, and 7, it replaces the following numbers (25-50) with "BuzzLightYear"
I have the numbers listed correctly, but when I run the program it prints the text along with the number when I just want the text instead of the number.
Here is my code:
int variable = 25;
while (variable <= 50)
{
Console.WriteLine(variable + "\n");
++variable;
if (variable % 2 == 0 && variable % 3 == 0 && variable % 7 == 0)
{
Console.Write("BuzzLightYear");
}
}
Console.ReadKey();
int variable = 25;
while (variable <= 50)
{
if (variable % 2 == 0 && variable % 3 == 0 && variable % 7 == 0)
{
Console.Write("BuzzLightYear\n\n");
}
else
{
Console.WriteLine(variable + "\n");
}
++variable;
}
Console.ReadKey();
int variable = 25;
while (variable <= 50)
{
if (variable % 2 == 0 && variable % 3 == 0 && variable % 7 == 0)
{
Console.Write("BuzzLightYear");
}
else{
Console.WriteLine(variable + "\n");
}
++variable;
}
Console.ReadKey();
The problem is that you're always printing the number. Just put that in an else instead.
But anytime you need a set number of iterations, a for loop is generally better because the loop variable declaration, condition, and increment are all in one place:
for (int variable = 25; variable <= 50; variable++)
{
if (variable % 2 == 0 && variable % 3 == 0 && variable % 7 == 0)
{
Console.WriteLine("BuzzLightYear");
}
else
{
Console.WriteLine(variable);
}
}
Console.ReadKey();
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.
I'm trying to use continue; but looks like - incorrect;
Every 3 times I have same "i" value. How can I skip iterator when running if(currentShiftCD != 3 & currentShiftAB == 3) and if(currentShiftDC != 3 & currentShiftBA == 3) for the first time after switching bools firsThreeDays and secondThreeDays
I want output to startlike: 1,2,3,4,5,6..19 but have with same values:
for (int i = 1; i <20; i++)
{
if (firstThreeDays)
{
if (currentShiftAB != 3)
{
currentShiftAB++;
Console.WriteLine(i + " A-B");
}
if (currentShiftCD != 3 & currentShiftAB == 3)
{
currentShiftCD++;
Console.WriteLine(i + " C-D");
}
if (currentShiftAB == 3 & currentShiftCD == 3)
{
firstThreeDays = false;
secondThreeDays = true;
currentShiftAB = 0;
currentShiftCD = 0;
continue;
}
}
if (secondThreeDays)
{
if (currentShiftBA != 3)
{
currentShiftBA++;
Console.WriteLine(i + " B-A");
}
if (currentShiftDC != 3 & currentShiftBA == 3)
{
currentShiftDC++;
Console.WriteLine(i + " D-C");
}
if (currentShiftBA == 3 & currentShiftDC == 3)
{
secondThreeDays = false;
firstThreeDays = true;
currentShiftBA = 0;
currentShiftDC = 0;
continue;
}
}
}
Console.ReadLine();
The problem is in the sequencing of your first two if statements, inside the firstThreeDays as well as secondThreeDays. Use if, else-if, else-if construct.
// Suppose your loop has executed once. Now, currentShiftAB is 2.
if (currentShiftAB != 3) // currentShiftAB is not 3.It enters this if.
{
currentShiftAB++; // currentshiftAB is now 3.
Console.WriteLine(i + " A-B"); //It prints 3 A-B
}
// Now, currentShiftAB is 3 but currentShiftCD is not 3.
// your code enters this if condition as well at the same time.
// That's why you are getting duplicate output for i=3.
if (currentShiftCD != 3 & currentShiftAB == 3)
{
currentShiftCD++;
Console.WriteLine(i + " C-D");
}
I wouldn't use continue to "solve" your problem just use the else clause with your first if
for (int i = 1; i <20; i++)
{
if (firstThreeDays)
{
if (currentShiftAB != 3)
{
currentShiftAB++;
Console.WriteLine(i + " A-B");
}
if (currentShiftCD != 3 & currentShiftAB == 3)
{
currentShiftCD++;
Console.WriteLine(i + " C-D");
}
if (currentShiftAB == 3 & currentShiftCD == 3)
{
firstThreeDays = false;
secondThreeDays = true;
currentShiftAB = 0;
currentShiftCD = 0;
}
}
else if (secondThreeDays)
{
if (currentShiftBA != 3)
{
currentShiftBA++;
Console.WriteLine(i + " B-A");
}
if (currentShiftDC != 3 & currentShiftBA == 3)
{
currentShiftDC++;
Console.WriteLine(i + " D-C");
}
if (currentShiftBA == 3 & currentShiftDC == 3)
{
secondThreeDays = false;
firstThreeDays = true;
currentShiftBA = 0;
currentShiftDC = 0;
}
}
}
Console.ReadLine();
This will guarantee that the if (secondThreeDays) block doesn't get run in the same iteration as the if (firstThreeDays) block.
This is not the actual code but it's what I want to do.
for loop is must but the nested if else loop inside should be executed according to the value of count_final which can be random between 1 to 3.
Like if the value of count_final is 3, all if...else loop should be considered. but if the value of count_final is 2, then only if...(1st)else if and else part only be executed. And if count_final=1 then only if and else part is executed (not any else-if).
Thought of putting another if...else within every if...else and checking count_final, but what if I'm not getting values of count2 and count3 when count_final=1.
Same, when count_final=2, I'm not getting the value of count3.
Ask in comment if you don't understand my question.
int count_final=Session["abc"];
//count_final=1;
//count_final=2;
//count_final=3;
for(int i=1;i<=10;i++)
{
if ((count1 <= count5) && (count1 <= count6))
{
Label1.Text="Hello1";
}
else if (count2 <= count4 && count2 <= count6)
{
Label2.Text="Hello2";
}
else if (count3 <= count4 && count3 <= count5)
{
Label3.Text="Hello3";
}
else
{
Label1.Text="Hello1";
}
}
Seems you have collection of "conditions" where amount of executed conditions depend on value of finalCount.
var rules = new Func<string>[]
{
() => (count1 <= count5 && count1 <= count6) ? "Hello1" : null,
() => (count2 <= count4 && count2 <= count6) ? "Hello2" : null,
() => (count3 <= count4 && count3 <= count5) ? "Hello3" : null
};
Label1.Text = rules.Take(finalCount)
.Select(rule => rule())
.Where(result => result != null)
.DefaultIfEmpty("Hello1")
.First();
Of course this solution is assuming that finalCount is always 1, 2 or 3.
DefaultIfEmpty is playing role of last else - will be used all conditions fails.
if i understand right.. which is a little unlikely
just add more criteria to your ifs!
if ((count1 <= count5) && (count1 <= count6))
{
if (count_final == 3 || count_final == 2) Label1.Text="Hello1";
}
else if (count2 <= count4 && count2 <= count6)
{
if (count_final == 3) Label2.Text="Hello2";
}
else if (count3 <= count4 && count3 <= count5)
{
if (count_final == 3) Label3.Text="Hello3";
}
else
{
if (count_final == 3 || count_final == 1) Label1.Text="Hello1";
}
Remembering that from what I understood there will be loops in that can achieve nothing, eg, if count_final == 2 and its not less or equal to count5 or count6, nothing will happen, same as for count_final == 1, if it matches any of the first bits the last else wont happen.
I suggest extending the conditions of your else if statements:
int count_final=Session["abc"];
//count_final=1;
//count_final=2;
//count_final=3;
for(int i=1; i<=10; i++)
{
if ((count1 <= count5) && (count1 <= count6))
{
Label1.Text="Hello1";
}
else if (count_final >= 2 && count2 <= count4 && count2 <= count6)
{
Label2.Text="Hello2";
}
else if (count_final >= 3 && count3 <= count4 && count3 <= count5)
{
Label3.Text="Hello3";
}
else
{
Label1.Text="Hello1";
}
}
When count_final == 1 this will not try to evaluate count2, count3 or count4 (which I understand is a requirement) because && will not evaluate its right hand side when there is false on the left.
Is this what you are looking for? To use less if/else statements:
int count_final = Session["abc"]; // random between 1 and 3
for(int i=1; i <= 10; i++)
{
switch(count_final)
{
case 3:
Label1.Text="Hello1";
// no break; so all gets executed
case 2:
Label2.Text="Hello2";
case 1:
Label3.Text="Hello3";
default: Label1.Text="Hello1";
}
}