C# - Loop ending result - c#

I'm going to try to explain this with the best of my ability, so please bear with me. I'm making a game, and basically there's 100 yards. you start at 100, and its on a loop, generating numbers and subtracting them from the 100 yards. Once the number hits 0, the loop will stop.
Take a look at this code:
int yardsLeft = 100;
// this is on a loop until 'yardsLeft = 0'
if (yardsLeft >= 80)
{
// 10% chance of generating a number 80-100
// 20% chance of generating a number 40-80
// 70% chance of generating a number 1-40
// Say it hits the 10% chance and generates the number 85 - there's 15 yards left
// it will pass through the if statements entering the `if (yardsLeft < 40)` - say that hits 20 once more. at the end once the yardsLeft finally equals 0, the yards added up each loop will be over 100. in this case 120
-------------------------------
// but if the generated number generates a 70% chance and hits a number 1-20, it's going to stay in the `yardsLeft > 80` if statment-
// therefore having the potential to exceed the number '100' once the `yardsLeft = 0`
}
else if (yardsLeft >= 40 && yardsLeft <= 79) { } // this would activate if the 20% chance got generated
if (yardsLeft < 40)
{
// 10% chance of generating a number 30-39
// 20% chance of generating a number 10-29
// 70% chance of generating a number 1-9
}
My problem:
if the generated number generates a 70% chance and hits a number 1-20, it's going to stay in the yardsLeft > 80 if statment,
therefore having the potential to exceed the number '100' once the yardsLeft = 0
So how if it did enter the yardsLeft >= 80, how can I make sure it generates a number that which at the end, it generated exactly 100 yards (numbers added up)
Here is my loop:
while (yardsLeft > 0)
{
int[] playResult = new int[i + 1];
playResult[i] = r.Next(1, 4);
switch (playResult[i])
{
case 1:
Console.WriteLine(BuffaloBills.QB + " hands it off to " + BuffaloBills.RB + " for a gain of " + Calculations.Play() + " yards. \n");
yardsLeft -= gained;
i++;
break;
case 2:
Console.WriteLine(BuffaloBills.QB + " passes it " + BuffaloBills.WR + " for a gain of " + Calculations.Play() + " yards. \n");
yardsLeft -= gained;
i++;
break;
case 3:
Console.WriteLine(BuffaloBills.QB + " doesn't find anyone open so he rushes for a gain of " + Calculations.Play() + " yards. \n");
yardsLeft -= gained;
i++;
break;
}
}
Here's my variables
public static Random r = new Random();
public static int gained;
public static int yardsLeft = 100;
public static int i = 0;
public static int chance = r.Next(1, 101);

Instead of just returning the number from your top if/else if/else statements, wait until the end of the block and return there. That will allow you to gather all of the logic to make the calculation in one spot.
private int Play(int yardsLeft) // Pass in the total yards left here
{
var yards = 0;
if (yardsLeft >= 80)
{
yards = // The result of your 10/20/70% calculation
}
else if (yardsLeft >= 40) { } // Same deal
else { } // Again, same as in the if
return yards > yardsLeft ? yardsLeft : yards;
}
You could also rework this to provide a string that would say whether or not a Touchdown was scored. (Have the yardsLeft parameter be a ref so that you can adjust the remaining yards inside this method.)

Related

How do I create a C# program that asks for a value between 1 and 100 that uses a loop

so I am trying to create a C# program that asks for a value between 1 and 100 that uses a loop to determine the sum of all values between 1 and the entered value and if the number entered in is less than one or more than 100 it prints out "Sorry. Try again." I've been working on this for days but I can't get it to print the sum, I keep getting 0 and whenever I test it and enter a number under one or over 100, it won't print the error message I want. Here is the code:
using System;
namespace PrintSumL
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a beginning value between 1 and 100");
int s = Convert.ToInt32(Console.ReadLine());
int sum = 0;
Console.WriteLine("Sum of values: " + sum);
Console.ReadKey();
Random rand = new Random();
rand.Next(1, 51);
while (0 < s && s < 101)
{
sum += s;
s++;
if (s < 0 && 101 < s)
{
Console.WriteLine("Invalid input. Try again.");
}
{
}
{
}
}
}
}
}
You can think of the program as executing line by line from top to bottom, and only moving back up when it reaches the end of the while loop. The end of the while loop is the } that matches the { at the start of the loop.
Knowing that, you can see why it always says sum is zero. From your code:
int sum = 0;
Console.WriteLine("Sum of values: " + sum);
Since the program executes "line by line from top to bottom", it will first set sum to 0, and then print sum out. So it will always print "Sum of values: 0". If you want it to print out the sum after it has calculated it, then you need to move the WriteLine down below where the sum is calculated.
The same issue applies to the "Invalid input. Try again.": the line that prints this statement appears after while (0 < s && s < 101), so will only execute if s is between 0 and 101. Since you're trying to catch the scenario where s is not between 0 and 101, you'll need to move the statement to above the while loop.
So, to fix your immediate problems, just do two things:
1) move the two lines
Console.WriteLine("Sum of values: " + sum);
Console.ReadKey();
to after the while loop (just after the } which is at the same level of indentation as while).
2) move the three lines
if (s < 0 && 101 < s)
{
Console.WriteLine("Invalid input. Try again.");
}
up to just below int s = Convert.ToInt32(Console.ReadLine());, and then double check the logic. It sounds like you want to print the statement if s is less than zero or s is greater than 101.
if loops are a requirement you should follow Heath Raftery instruction
else you could write something like:
static void Main(string[] args)
{
Console.WriteLine("Enter a beginning value between 1 and 100");
int s = Convert.ToInt32(Console.ReadLine());
if (s < 0 || s > 100)
Console.WriteLine("Invalid input. Try again.");
else
Console.WriteLine($"Sum of values: {Enumerable.Range(1,s).Sum()}");
}
or as haldo commented you could just use the formula of N * (N+1) / 2 and replace the last WriteLine with:
Console.WriteLine($"Sum of values: {s * (s+1) / 2}")
Try this:
static void Main(string[] args)
{
while (true)
{
Console.Write("Enter a number between 1 and 100: ");
int Number = Convert.ToInt32(Console.ReadLine());
if (Number < 0 || Number > 100)
Console.WriteLine("Sorry. Try again.");
else
{
int sum = 0;
for (int i = 1; i <= Number; i++)
{
sum = sum + i;
}
Console.WriteLine("Sum of values: " + sum);
}
}
}
Here is an algorithm that works...
Console.WriteLine("Enter a value between 1 and 100");
var input = int.Parse(Console.ReadLine());
int sum = 0;
if (input<1 || input>100) {
Console.WriteLine("Sorry, Try again");
}
else{
while(input > 2){
input-=1;
sum+=input;
}
}
Console.WriteLine("Sum of values: " + sum);

Unexpected results when counting how often sequences occur in a random distribution

Given a coin game: you start with a dollar and a coin is flipped. If it's heads the dollar is doubled, if it's tails the game ends. However if head's is flipped again the payoff is now quadrupled and if head is flipped 3 times 8x and so on. The paradox is that the expect value is 1/2*1+1/4*2+1/8*4... = infinity.
So you if you play the game long enough you should be getting progressively richer. Monte carlo simulation suggests not.
This is simulation of the famous St. Petersburg Paradox
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sorrow
{
class Program
{
static void Main(string[] args)
{
Random rnd = new Random(Environment.TickCount);
double totalSum = 0;
int bigWins = 0;
double iterations = 1000;
for (int z = 0; z < 10; z++)
{
iterations *= 10;
for (double i = 1; i < iterations; i++)
{
int sum = 1;
int a = 1;
while (a == 1)
{
//generate a random number between 1 and 2
a = rnd.Next(1, 3);
if (a == 1)
{
sum *= 2;
}
if (sum > 8000&&sum<12000)// given discrete probability landing 13 times
{
// if the sum is over 8000 that means that it scored 1 13 times in a row (2^13) - that should happen
//once every 8192 times. Given that we run the simulation 100 000 000 times it should hover around
// 100 000 000/8192
//However is much , much bigger
bigWins++;
}
}
totalSum += sum;
}
Console.WriteLine("Average gain over : "+iterations+" iterations is:" + totalSum / iterations);
Console.WriteLine("Expected big wins: " + iterations / 8192 + " Actual big wins: " + bigWins);
Console.WriteLine();
}
}
}
}
As you can see we should expect 7 times smaller number. This makes me think that perhaps c# random is prone to choosing the same number over and over again?
Is it true or there is something wrong with my code?
How might I fix the issue?
You have two bugs. Your loop starts after a win, so the chance of a big win is 1/2^12, and you keep incrementing bigwins for additional wins after 12.
Try
static void Main(string[] args)
{
Random rnd = new Random(Environment.TickCount);
double iterations = 1000;
for (int z = 0; z < 10; z++)
{
double totalSum = 0;
int bigWins = 0;
iterations *= 10;
for (double i = 1; i < iterations; i++)
{
int sum = 2;
int a = 1;
while (a == 1)
{
//generate a random number between 1 and 2
a = rnd.Next(1, 3);
if (a == 1)
{
sum *= 2;
}
if (sum > 8000)
{
// if the sum is over 8000 that means that it scored 1 12 times in a row (2^12) - that should happen
//once every 4096 times. Given that we run the simulation 100 000 000 times it should hover around
// 100 000 000/4096
bigWins++;
break;
}
}
totalSum += sum;
}
Console.WriteLine("Average gain over : " + iterations + " iterations is:" + totalSum / iterations);
Console.WriteLine("Expected big wins: " + iterations / 4096 + " Actual big wins: " + bigWins);
Console.WriteLine();
}
Console.ReadKey();
}
outputs something like:
Average gain over : 10000 iterations is:12.6774
Expected big wins: 2.44140625 Actual big wins: 1
Average gain over : 100000 iterations is:14.09468
Expected big wins: 24.4140625 Actual big wins: 21
Average gain over : 1000000 iterations is:14.022718
Expected big wins: 244.140625 Actual big wins: 249
Average gain over : 10000000 iterations is:14.0285748
Expected big wins: 2441.40625 Actual big wins: 2456
Average gain over : 100000000 iterations is:14.00012582
Expected big wins: 24414.0625 Actual big wins: 24574
Average gain over : 1000000000 iterations is:14.000105548
Expected big wins: 244140.625 Actual big wins: 244441
Average gain over : 10000000000 iterations is:13.9990068676
Expected big wins: 2441406.25 Actual big wins: 2440546
What you are looking for is the probability that the game gets to or continues past $8000 which is 1 minus the sum of the probabilities of ending before $8000
Probability of ending after...
0 rounds 1/2 $2
1 round 1/4 $4
2 rounds 1/8 $8
3 rounds 1/16 $16 (same as 1/(2^(rounds+1))
...
12 rounds 1/2^13 $8192 (in your code you are off by one round, you get to $8192 after 12 wins, not 13
sum all of the probabilities of ending before $8192 and you get 0.999755859
So... your probability of a game getting to at least $8192 is 1-0.999756 or 0.000244141
Compare this to the probability of 1/8192 = 0.0001220703125 and you see you are off by about a factor of 2.
This doesn't change the fact that Random isn't a good approximation of random, and your expected results will still be off.
If you want to use RNGCryptoServiceProvider you can do the following
initialize a RNGCryptoServiceProvider somewhere in your class
RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
Then where you are assigning the value a you can do the following
//generate a random number between 1 and 2
//allocate an array of bytes to be populated by rngCsp
byte[] randomNumber = new byte[1];
//populate the array with a random byte
rngCsp.GetBytes(randomNumber);
//if the random byte is [0,125] return 1 and if [126,255] return 2
a = randomNumber[0] < 126 ? 1 : 2;
If you are interested in calculating the count of how many times a sequence of 13 or more ones occur, the below code may be of interest to you. It may not be as fast as the original code, but I think it may be slightly easier to read and understand (which I think is important, but because part of the reason why it took so long to spot the bugs in the original code was that it was a little hard to follow the logic). Basically, it keeps a queue of the last 13 items, and checks whether they are all 1.
Note that the calculation I have used to determine the expected number of sequences is also different to yours. I don't just divide by 8192, instead I do (iterations - (iterations * (1 - (1m/8192m)))). I don't think that calculation is 100% right, but it is more accurate than the original.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp4
{
internal class Program
{
private static void Main(string[] args)
{
var queue = new Queue<int>();
var rnd = new Random(Environment.TickCount);
int bigWins = 0;
long iterations = 10000000;
const int sequenceLength = 13;
double probability = 1 / Math.Pow(2, sequenceLength);
for (int z = 0; z < iterations; z++)
{
var a = rnd.Next(1, 3);
queue.Enqueue(a);
if (queue.Count == sequenceLength)
{
if (queue.Distinct().Count() == 1 && queue.First() == 1)
{
bigWins++;
}
queue.Dequeue();
}
}
Console.WriteLine("Expected big wins: " + (iterations - (iterations * (1 - probability))) + " Actual big wins: " + bigWins);
Console.ReadLine();
}
}
}

having trouble with passing array

I'm having issues with passing array values. I've been working on this for hours and can't seem to find the answer. wonder if someone can point me in the right direction. This is what I have so far. I've looked at countless examples, videos and reading material and can't seem to come up with the solution. I would really appreciate the help.
static void Main(string[] args)
{
int Seed = 0;
int[] random = new int[10];
int[] input = new int[10];
for (int x = 0; x < random.Length; x++)
{
Seed = (int)DateTime.Now.TimeOfDay.Ticks;
random[x] = getRnd(Seed);
}
for (int x = 0; x < input.Length; x++)
{
Console.Write("Enter an integer number between 1 and 100: ");
input[x] = Convert.ToInt32(Console.ReadLine());
}
int inputnumber=input[0];
for (int x = 0; x < input.Length; x++)
if (inputnumber <= random[x])
{
Console.WriteLine("The entered number " + inputnumber + " is less than " + random[x]);
}
else if (inputnumber >= random[x])
{
Console.WriteLine("The entered number " + inputnumber + " is greater than " + random[x]);
}
else if (inputnumber == random[x])
{
Console.WriteLine("The entered number " + inputnumber + " is equal to " + random[x]);
}
}
static int getRnd(int Seed)
{
Random myrandomnum = new Random(Seed);
int randomvalue = myrandomnum.Next(1, 100);
return randomvalue;
}
}
}
I need it to print like this.
Enter an integer number between 1 and 100: 1
Enter an integer number between 1 and 100: 8
Enter an integer number between 1 and 100: 44
Enter an integer number between 1 and 100: 22
Enter an integer number between 1 and 100: 16
Enter an integer number between 1 and 100: 88
Enter an integer number between 1 and 100: 41
Enter an integer number between 1 and 100: 77
Enter an integer number between 1 and 100: 10
Enter an integer number between 1 and 100: 52
The entered number 1 is less than 64
The entered number 8 is less than 44
The entered number 44 is less than 80
The entered number 22 is less than 91
The entered number 16 is less than 95
The entered number 88 is greater than 39
The entered number 41 is less than 79
The entered number 77 is greater than 27
The entered number 10 is less than 35
The entered number 52 is less than 65
Press any key to continue . . .
But I'm getting this:
Enter an integer number between 1 and 100: 1
Enter an integer number between 1 and 100: 8
Enter an integer number between 1 and 100: 44
Enter an integer number between 1 and 100: 22
Enter an integer number between 1 and 100: 16
Enter an integer number between 1 and 100: 88
Enter an integer number between 1 and 100: 41
Enter an integer number between 1 and 100: 77
Enter an integer number between 1 and 100: 10
Enter an integer number between 1 and 100: 52
The entered number 1 is less than 64
The entered number 1 is less than 64
The entered number 1 is less than 64
The entered number 1 is less than 64
The entered number 1 is less than 64
The entered number 1 is less than 64
The entered number 1 is less than 64
The entered number 1 is less than 64
The entered number 1 is less than 64
The entered number 1 is less than 64
Press any key to continue . . .
There are two problems - one explaining why you're only using the first input number, and one explaining why you're only comparing it against one random number.
For the random number part, here's the problem:
Seed = (int)DateTime.Now.TimeOfDay.Ticks;
random[x] = getRnd(Seed);
...
static int getRnd(int Seed)
{
Random myrandomnum = new Random(Seed);
Unless DateTime.Now.TimeOfDay.Ticks changes between iterations - which is very unlikely, as the system clock resolution is usually in the order of milliseconds, and you're not doing a lot of work between iterations - you're creating multiple instances of Random, all with the same seed. That means you'll get the same sequence of random numbers from each instance - but you're actually only asking for one number from each instance anyway.
The solution is to create a single Random instance, and then use that for every random number you generate.
Random rng = new Random();
for (int x = 0; x < random.Length; x++)
{
random[x] = GenerateRandomValue(rng);
}
...
static int GenerateRandomValue(Random random);
{
int randomvalue = random.Next(1, 100);
return randomvalue;
}
Of course at that point you may consider removing the method entirely, and using:
Random rng = new Random();
for (int x = 0; x < random.Length; x++)
{
random[x] = random.Next(1, 100);
}
You might also want to consider using random.Next(1, 100) if you want a value between 1 and 100 inclusive - the second argument to Random.Next is an exclusive upper bound.
Note that this approach to creating a single instance of Random doesn't play well in a multi-threaded scenario, as Random isn't thread-safe. Fortunately that's not a problem here, but see my article on Random for more information if you need it later.
For the "only using a single input value" problem, LaD1Da's answer goes into more detail, but the issue is that inputNumber is always input[0]... you're never using input[1], input[2] etc.
I have not enough 'Reputation' to simply add a comment:
The issue is that you do not change the inputnumber in your last loop. You always use input[0]. Simply change the last loop to the following:
for (int x = 0; x < input.Length; x++)
int inputnumber = input[x]; // This is new
if (inputnumber <= random[x])
{
Console.WriteLine("The entered number " + inputnumber + " is less than " + random[x]);
}
else if (inputnumber >= random[x])
{
Console.WriteLine("The entered number " + inputnumber + " is greater than " + random[x]);
}
else if (inputnumber == random[x])
{
Console.WriteLine("The entered number " + inputnumber + " is equal to " + random[x]);
}
}
Edit: Additionally you have an issue with your random number generation. Refer to Jon Skeet's answer for that.
There are two problems.
The first problem is in getRnd(). On each iteration of the loop you are passing a new seed, but the loop is executing so fast that it is likely that the number of Ticks will be the same on each iteration. You can fix this by moving the seeding outside of the loop, and passing the Random generator as a parameter to the getRnd() function:
Seed = (int)DateTime.Now.TimeOfDay.Ticks;
Random rand = new Random(Seed);
for (int x = 0; x < random.Length; x++)
{
random[x] = getRnd(rand);
}
The second problem is in your loop. On this line:
int inputnumber=input[0];
You assign the value in input[0] to inputnumber. However, you never change it on future iterations of the loop. You can fix this by iterating through input[] at each loop iteration, i.e.:
for (int x = 0; x < input.Length; x++)
{
if (input[x] <= random[x])
{
Console.WriteLine("The entered number " + input[x] + " is less than " + random[x]);
}
else if (input[x] >= random[x])
{
Console.WriteLine("The entered number " + input[x] + " is greater than " + random[x]);
}
else if (input[x] == random[x])
{
Console.WriteLine("The entered number " + input[x] + " is equal to " + random[x]);
}
}

Calculating the note mix to dispense

I need to figure out a cash mix algorithm to dispense notes from the ATM. The goals of the algorithm are:
To calculate the note mix to dispense the required amount to the customer.
While doing so, to attempt the emptying of the cash cassettes as evenly as possible, so ideally (but not mandatory), the cash will run out in all cassettes at the same time.
The user wants to get different amounts of cash, such as 500$, 1200$, 6000$, etc.
There is no average. The algorithm needs to figure out which notes and how many of them to dispense. Of course, the cassettes in the ATM can change to different values / counts.
Another limitation is that the ATM can present only 30 notes at the time, so the algorithm has to divide the notes in bunches, if calculated number of notes exceeds this limit, while considering the goal above (equal emptying).
Here is what i came up with:
//Represents a typical cash cassette.
class Cassette
{
public int Denom { get; set; } //Denomination: (USD)50, (USD)100, etc.
public int Count { get; set; } //Number of notes.
}
//Our cassettes.
List<Cassette> OriginalCashCassettes = new List<Cassette>();
List<Cassette> CloneCashCassettes = new List<Cassette>();
//Populated.
OriginalCashCassettes.Add(new Cassette { Denom = 50, Count = 1000 });
OriginalCashCassettes.Add(new Cassette { Denom = 100, Count = 1000 });
OriginalCashCassettes.Add(new Cassette { Denom = 200, Count = 1000 });
//Pass original cassettes to clone cassettes.
CloneCashCassettes = OriginalCashCassettes;
//Calculate mix for requested amount.
CalculateNoteMix(6000);
And the calculation itself:
private void CalculateNoteMix(int reqAmount)
{
//1. Check if the amount is higher than combined counts.
int totalCounts = 0;
foreach (var item in CloneCashCassettes)
{
totalCounts += item.Denom * item.Count;
}
if (totalCounts < reqAmount)
{
Console.WriteLine("You're trying too high - maximum amount available is: " + totalCounts);
return;
}
//2. Check if the amount is dispensable with current denoms.
int lowestDenom = CloneCashCassettes.Min(c => c.Denom);
if (reqAmount % lowestDenom != 0)
{
Console.WriteLine("Unable to dispense amount with current denoms");
return;
}
//3. Calculate note mix to dispense.
List<Cassette> noteMix = new List<Cassette>();
do
{
//Sort cash cassettes by highest count first.
CloneCashCassettes = CloneCashCassettes.OrderByDescending(c => c.Count).ToList();
//Check if highest count denom can cover the amount.
if (CloneCashCassettes[0].Denom <= reqAmount)
{
//Check if this denom already exists in the mix.
Cassette noteMixCassette = noteMix.Find(n => n.Denom == CloneCashCassettes[0].Denom);
if (noteMixCassette == null)
{
//Add denom to the note mix.
noteMix.Add(new Cassette { Denom = CloneCashCassettes[0].Denom, Count = 1 });
}
else
{
//Increase denom count in the note mix.
noteMixCassette.Count += 1;
}
//Reduce denom count in the cash cassette.
CloneCashCassettes[0].Count -= 1;
//Reduce the amount by denom.
reqAmount -= CloneCashCassettes[0].Denom;
}
else
{
//The amount is smaller than denom => the denom is unusable - remove it.
CloneCashCassettes.RemoveAt(0);
}
//Keep looping until the amount is 0.
} while (reqAmount > 0);
//Print resulting note mix.
Console.WriteLine("For the amount of " + reqAmount + ", our note mix is:");
foreach (var item in noteMix)
{
Console.WriteLine("Denom: " + item.Denom + " x " + "Count: " + item.Count + " = " + item.Denom * item.Count);
}
}
Using this code, if the user asks for $400, then the note mix is:
Denom: 50 x Count: 2 = 100
Denom: 100 x Count: 1 = 100
Denom: 200 x Count: 1 = 200
Or if the user asks for $25,000, then:
Denom: 50 x Count: 72 = 3600
Denom: 100 x Count: 72 = 7200
Denom: 200 x Count: 71 = 14200
Problems:
This code appears to work fine with denoms of 50 and higher. However, it has a problem with the denom of 20. Any idea how to resolve it?
Example:
OriginalCashCassettes.Add(new Cassette { Denom = 20, Count = 1000 });
OriginalCashCassettes.Add(new Cassette { Denom = 50, Count = 1000 });
OriginalCashCassettes.Add(new Cassette { Denom = 100, Count = 1000 });
The user asks for $200, which is dispensable.
I start to subtract: 200-100-50-20 = 30 - 20 = 10 -> unable to dispense.
Same problem with denom of 20 exists in the check if the amount is dispensable (#2 in code).
Example: The cassettes configured as above with denom of 20. User asks for $210, which should be dispensable (100+50+20+20+20).
Any ideas how to improve this algorithm in general, so it will be more efficient / faster?
Thanks.
The problem you've encountered, basically, is that you're algorithm leads you to a place where you cannot dispense any more... a dead end (ie, left with $10 to dispense but you do not have that denomination).
What I would do to combat this is to generate all possible permutations of valid dispensations, and then pick which one is "best" or most optimal in terms of rules such as "even dispensation of bills". There may be some shortcuts you can take later on, such as ruling out obviously bad choices, but you'll understand the "optimization" bit much easier if the thing actually works!
I started off with this example (http://www.dotnetperls.com/change) which is a rather rudimentary algorithm for determining the permutations of change available for a given set of coins and a required amount. This is the same basic problem as yours.
public static void Main(string[] args)
{
List<int> notes = new List<int>();
List<int> amounts = new List<int>() { 50,100,200 };
Change(notes, amounts, 0, 0, 250);
}
static void Change(List<int> notes, List<int> amounts, int highest, int sum, int goal)
{
//
// See if we are done.
//
if (sum == goal)
{
Display(notes, amounts);
return;
}
//
// See if we have too much.
//
if (sum > goal)
{
return;
}
//
// Loop through amounts.
//
foreach (int value in amounts)
{
//
// Only add higher or equal amounts.
//
if (value >= highest)
{
List<int> copy = new List<int>(notes);
copy.Add(value);
Change(copy, amounts, value, sum + value, goal);
}
}
}
Here is a live example: http://rextester.com/HIJEQC83701
Asking this code for the permutations for $250 using combinations of 50's,100's and 200's gives the following output:
50: 5
100: 0
200: 0
50: 3
100: 1
200: 0
50: 1
100: 2
200: 0
50: 1
100: 0
200: 1
From there, its easy enough to pick the option that either
a) Uses the most even spread of notes
b) Uses a spread of notes which leaves the overall casettes in the most balanced position.
I'll leave that bit to you!

How to make each number, 1-1000, to show what it is e.g. odd/even, more than 500

OK. I have been trying this code for a long time now. I want to write a program which prints out the numbers 1-1000. For each number, I want it to show if it is odd/even, whether or not it is smaller than 250, bigger than or equal to 250 and less than 500, bigger than or equal to 500 and less than 750 or bigger than or equal to 750. This is my code, but it doesn't work, and I have searched over the IE and found nothing to help.
for (int i = 0; i < 1001; i++) ;
if ((i % 2) == 0)
{
Console.WriteLine(i + " is even ");
}
else
{
Console.WriteLine(i + " is odd ");
}
if (i < 250)
{
Console.WriteLine(" is less than 250");
}
else
{
Console.WriteLine("");
}
if (i >= 250)
{
if (i < 500)
{
Console.WriteLine(" is greater than or equal to 250 and less than 500 ");
}
else
{
Console.WriteLine("");
}
if (i >= 500)
{
if (i < 750)
{
Console.WriteLine(" is greater than or equal to 500 and less than 750 ");
}
else
{
Console.WriteLine("");
}
if (i >= 750)
{
Console.WriteLine(" is greater than or equal to 750 ");
}
else
{
Console.WriteLine("");
}
Console.ReadLine();
I think it is the "i" s as there are errors saying that it doesn't exist in the current context. How do make it so it doesn't say that at makes the code better? Have I got the rest correct. Please help.
Your for loop never executes anything, except "empty instructions". Remove the ; at the end:
for (int i = 0; i < 1001; i++) ;
Also surround the following instructions with curly braces:
for (int i = 0; i < 1001; i++)
{
// rest of instructions
}
Trying removing the ; behind it, and enclosing the rest of your code in {…}.
You can also reduce the size of your code significantly by merging your if…else statements together, and removing redundant checks.
Finally, don’t forget to place your Console.ReadLine outside the loop (unless you want to pause the program after each number).
for (int i = 0; i < 1001; i++)
{
if ((i % 2) == 0)
Console.Write(i + " is even ");
else
Console.Write(i + " is odd ");
if (i < 250)
Console.WriteLine("and is less than 250");
else if (i < 500)
Console.WriteLine("and is greater than or equal to 250 and less than 500 ");
else if (i < 750)
Console.WriteLine("and is greater than or equal to 500 and less than 750 ");
else
Console.WriteLine("and is greater than or equal to 750 ");
}
Console.ReadLine();
As Tudor pointed, you should remove the ; after the for statement.
You've also forgotten to wrap everything that should be inside the loop in curly braces, { and }.

Categories