For-Statement, Each 1000th Walkthrough, do something - c#

I'm walking through a Forloop 100'000 times. (that number can be diversified)
Every 1000th time I want do something specially, what I don't do in the other walkthroughs.
Something like that:
for (int i = 0; i < 100000; i++)
{
doTasks(); //Normal
if(i == 1000 || i == 2000 || i == 3000 || i == 4000 ) //and so on...
{
doSomethingElse(); //Special, For every 1000th walkthrough
}
}
What would be the most efficient way to accomplish that task?

Try with a modulo operator. Not sure about the C# syntax, but something like:
if(i % 1000 == 0)
{
//Do something
}

if (i != 0 && i % 1000 == 0)
It means if i mod 1000 is 0 (so on 1000, 2000, 3000, ...) but not on i == 0

if (i != 0 && i % 1000 == 0) {
doSomethingElse();
}
% is the modulus operator, returning the remainder of a division operation. If the remainder is zero then you have a multiple of 1000. However you need to exclude 0 specifically because 0 is evenly divisible by 1000 as well.

Using the modulo operator:
if (i % 1000 == 0) {
// do something...
will do what you want.
It divides by the given argument (in this case, 1000) and gives you the remainder. In this case you're interested in a remainder of 0. See the doc for the modulo operator here

I'm really nitpicking here, and potentially answering a dead horse, but do this:
if(i%1000 == 999) ...
Instead of comparing to 0 and avoiding the first iteration.

use operator % http://msdn.microsoft.com/en-us/library/6a71f45d.aspx

Related

if statement with multiple conditions instead of using AND

I been searching for some information about if statements with multiple conditions but haven't found something that corresponds to myquestion.
I was wondering if you could write:
int n = 3
if (3 < n < 20)
{
//do something..
}
rather than doing:
if (n > 3 && n < 20)
{
//do something..
}
The first statement doesn't work for me which i think it should, because it's plain simple.
Maybe someone can give me the correct syntax for doing so or maybe it's just impossible at all and i just have to go with the AND.
To explain why it's invalid:
if (3 < n < 20)
Could be rewritten as:
if ((3 < n) < 20)
Now 3 < n's outcome would be a bool.
So basically you'll get:
if (true/false < 20)
Which is not valid in C#.
Stefan's answer explains why it's impossible.
But here is a workaround, if you don't want to write that pesky && explicit conditions every time - you can create an extension method:
public static class IComparableExtensions
{
public static bool Between<T>(this T self, T low, T high) where T : IComparable
{
return self.CompareTo(low) > 0 && self.CompareTo(high) < 0;
}
}
And use it like this:
int n = 5;
if(n.Between(3, 20))
{
// do your stuff here
}
Please note, however, that this might be confusing - since Between doesn't specify if the compare is inclusive, exclusive, or inclusive in only one direction - so if you compare, say, 20.Between(10, 20) - should it return true or false?
A better approach would require adding another variable to the method, to indicate that:
[Flags]
public enum CompareMode
{
Exclusive = 0,
IncludeLow = 1,
IncludeHigh = 2,
Inclusive = IncludeLow | IncludeHigh
}
public static class IComparableExtensions
{
public static bool Between<T>(this T self, T low, T high, CompareMode mode) where T : IComparable
{
var compareLow = (mode & CompareMode.IncludeLow) == CompareMode.IncludeLow ? 0 : 1;
var compareHigh = (mode & CompareMode.IncludeHigh) == CompareMode.IncludeHigh ? 0 : -1;
return self.CompareTo(low) >= compareLow && self.CompareTo(high) <= compareHigh;
}
}
Now you use it like this:
if(n.Between(3, 20, CompareMode.Exclusive))
{
// do your stuff here
}
You can see a live demo on rextester.
This way, another person reading this code (or even you, 6 months from now) will know immediately, without having to look inside the Between extension method, if between is inclusive, exclusive, or whatever.
Generally it is not possible what you want to do.
but in your logic if you want to perform single liner logic you can use ternary operator.
for eg. you need to assign value of n to variblae result else it should be 0 as default.
int result = n > 3 ? (n < 20 ? n : 0) : 0
it is equivalent to
int result = 0;
if (n > 3 && n < 20)
{
result = n;
}

Easier way to 'or' operators in if statements (C#)

I'm making a game in unity, and I have this 'if statement' that by every 5 waves my shop menu will become visible. The code does work, but I am certain I'm doing something wrong or could do something better!
if (waveCount == 5 || waveCount == 10 || waveCount == 15 || waveCount == 20 || waveCount == 25 || waveCount == 30 || waveCount == 35 || waveCount == 40 || waveCount == 45 || waveCount == 50)
{
// yield return new WaitForSeconds(shopWait);
shopPanel.SetActive(true);
}
As you can see the 'if statement' not that good, normally it continues all the way to waveCount == 100 but i cut that out. There must be a simpler or cleaner way to do this :/ but i just can't wrap my head around it :(
Edit 1:
Thanks, I didn't know much about modulo, know I know what I have to read about :)
You can use modulo operation:
if (waveCount % 5 == 0)
Yes, there are indeed simpler ways of doing this. If you use a little bit of maths and logic, you can figure this out.
Since you want to check whether the value of waveCount is a multiple of 5, you can use % to get the reminder of waveCount / 5. If that reminder is 0, waveCount is a multiple of 5.
if (waveCount % 5 == 0 && waveCount <= 100)
I added waveCount <= 100 to replicate your code's behaviour when waveCount is larger than 100 i.e. not get into the if statement.
Alternatively, you can put all the values into a list:
var list = new List<int>();
for (int i = 1 ; i <= 20 ; i++) {
list.Add(i * 5);
}
And then check whether the list contains the number:
if (list.Contains(waveNumber))
The advantage of this is that if you decided to change how the game works and say that the shop menu can be opened at waves 9, 52, and 77, you just add the numbers to the list, without modifying the if statement. This provides a lot of flexibility.
if (waveCount % 5 == 0 && waveCount <= 50) {
//...code
}
If your “if” statement's body just contains shopPanel.SetActive(true); you can do that without even using “if” like that.
shopPanel.SetActive(waveCount % 5 == 0 && waveCount <= 50);
Give it a try
if (waveCount % 5 == 0 && waveCount <= 50)
Use the modulo-operator:
if(waveCount % 5 == 0 && waveCount <= 100) ...
The operator calculates the remainder of an integer-divison. In your case the statement should return zero indicating that your number divided by 5 has no remainder.
Just to generalize: in case the data you have doesn't match a pattern, you can put all the things to match against in a set, then test the set for membership:
var thingsToMatch = Set(2, 5, 8, 14, 23, 80, 274...);
if (someNumber in thingsToMatch) {...}
As long as you know the set isn't being recreated everytime the function is called, this has proven to be fairly fast. If your language doesn't automatically cache the set, you can make it a static variable of the function.
You can use the remainder operator for this:
if (waveCount % 5 == 0 && waveCount > 0 && waveCount <= 50)
{
//yield return new WaitForSeconds(shopWait);
shopPanel.SetActive(true);
}
You can test whether the remainder of the division by 5 is 0, which means that the number is divisible by 5.
if (waveCount % 5 == 0 && waveCount >= 5 && waveCount <= 50)
C# performs integer math on integer number types (int, long, uint, ...).
Example:
13 / 5 = 2
I.e. you never get a decimal fraction part. The complementary operation is the modulo operation. It gives you the remainder of this division:
13 % 5 = 3
I.e., 13 / 5 is 2 plus remainder 3. Together, division and modulo operation allow you to perform the reverse operation.
(5 * (13 / 5)) + (13 % 5) =
(5 * 2 ) + ( 3 ) = 13
If you have irregular figures, quite different approaches are to use a switch statement:
switch (waveCount) {
case 5:
case 10:
case 15:
case 20:
case 25:
case 30:
case 35:
case 40:
case 45:
case 50:
shopPanel.SetActive(true);
break;
}
or an array of allowed values:
private static readonly int[] AllowedValues =
new int[] { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
if(Array.IndexOf(AllowedValues, waveCount) >= 0) { ... }

Code not returning expected number of even and odds

I have a function that takes in a list of numbers and will return how many even numbers and odd numbers there are in the list. However, I passed in a list of numbers but I'm getting 0 results.
Here is my function -
public static string HowManyEvenAndOdds(List<int> numbers)
{
int numOfOdds = 0;
int numOfEvens = 0;
int numOfBoth = 0;
foreach (int i in numbers) {
bool isEven = i % 2 == 0;
bool isOdd = i % 3 == 0;
numOfBoth = isEven && isOdd ? numOfBoth++ : numOfBoth;
numOfEvens = isEven ? numOfEvens++ : numOfEvens;
numOfOdds = isOdd ? numOfOdds++ : numOfOdds;
}
return string.Format("This list has {0} odd numbers,\n{1} even numbers,\nand {2} numbers that are even and odd.", numOfOdds, numOfEvens, numOfBoth);
}
Any ideas on what I'm doing wrong here? I debugged through it but none of the lists are incrementing.
Thanks
your are not calculating odd in the correct way
i%3 does not catch 5 which is also an odd number, try this instead
bool isEven = i % 2 == 0;
bool isOdd =!isEven;
I agree with Schachaf Gortler's answer as well as p.s.w.g's comment. Just do:
foreach (var number in numbers)
{
// A number is even if, and only if, it's evenly divisible by 2
if (number % 2 == 0)
numEvens++;
// A number is odd if, and only if, it's NOT evenly divisible by 2
// Alternatively, a number is odd if it isn't even and vice versa
else
numOdds++;
}
As p.s.w.g. mentioned, there's no such thing as a number that's both even and odd, so eliminate that completely.
Incidentally, numOfEvens++ retrieves the value and then increments it, which is why your code didn't work.
I think you should have a look at your test for isOdd
Use the Linq Count extension.
int numOfOdds = numbers.Count(x => x % 2 != 0);
int numOfEvens = numbers.Count(x => x % 2 == 0);
Of course you don't need to evaluate both expressions, as per the comment below.

C#: Choosing operator depending on boolean value (in one line)

I'm trying to get away with a slick one liner as I feel it is probably possible.
I'll put my code below and then try to explain a little more what I'm trying to achieve.
for (int p = 0; p < 2; p++)
{
foreach (string player in players[p])
{
if (PlayerSkills[player].streak_count *>* 0) //This line
PlayerSkills[player].streak_count++;
else
PlayerSkills[player].streak_count = 0;
}
}
*(p==0 ? >:<) the comparison operator is chosen depending on p.
Of course what I've written is rubbish. But basically I want to use >0 when p==0, and <0 when p>>0. Is there a nice way to achieve this?
Well, you should use what is most readable, even if it is not as consice. That said...
// Invert the count for all but the first player and check for a positive number
if (PlayerSkills[player].streak_count * (p==0 ? 1 : -1) > 0)
I don't know about slick, but the following and/or combination is one line:
if ((p == 0 && PlayerSkills[player].streak_count > 0)
|| PlayerSkills[player].streak_count < 0)
...
This will only ever do the array index once (due to the p==0 condition occurring first) and so is equivalent to the "ternary" you wrote (albeit a bit more verbose).
p > 0 ? whenGreaterThanZero : whenZeroOrLess ;
E.g.
int p = 1; bool test = p > 0 ? true : false ;
Lets test = True

C# A loop using while. Variable displayed only once

I have a small problem. My code is this one :
int c = 0;
int i = 0;
int a = 28;
while (i < a) {
i++;
if (i % a == 0) {
c += i;
Console.WriteLine(i.ToString());
}
}
Why does the string i is displayed only once, after the end of the while ? It should be displayed a times.
Your help will be appreciated !
Your if condition is opposite it should be:
if (a % i == 0)
Currently you are trying to do remainder division with i % a and it will only meet the condition when i reaches 28, so you get the output once.
% is for modulus division, which basically divides by the number and gives you back the remainder. When you're loop reaches 28 it divides it by 28 and the resulting remainder is 0. This only happens once "when your loop reaches 28".
It would help if you told us what was printed out. I guess it is 28 because
i % a
returns the reminder of
i / a
(i divided by a) and it is only 0 when i is equal to a, i.e., 28.

Categories