I have the following code, the program supposed to count down by ten until 30, after that by 5 until 10 and the count down by 1. It's work fine counting by ten, but never reach Decrement(ref remainingTime, 5);
I am new to programming, any hint is welcomed. Thank you!
static void Main(string[] args)
{
int initialTime = Convert.ToInt32(Console.ReadLine());
int remainingTime = initialTime;
while (remainingTime > 0)
{
if (remainingTime > 30)
{
Decrement(ref remainingTime, 10);
break;
}
if (remainingTime > 10)
{
Decrement(ref remainingTime, 5);
break;
}
Decrement(ref remainingTime);
break;
}
Console.Write("0\n");
Console.Read();
}
static void Decrement(ref int baseValue, int step = 1)
{
for (int i = baseValue; i >= 0; i -= step)
{
Console.WriteLine(i);
}
}
CodePudding user response:
You should delete break
statement after Decrement
call in if
statement
Your code never reach Decrement(ref remainingTime, 5);
because you have break
statement in if (remainingTime > 30)
condition body. It stops your loop and code goes further, already outside the loop.
I'd advise you to learn how to use the debugger. This is a very good skill.
static void Main(string[] args)
{
int initialTime = Convert.ToInt32(Console.ReadLine());
int remainingTime = initialTime;
while (remainingTime > 0)
{
if (remainingTime > 30)
{
Decrement(ref remainingTime, 10);
}
if (remainingTime > 10)
{
Decrement(ref remainingTime, 5);
}
Decrement(ref remainingTime);
break;
}
Console.Write("0\n");
Console.Read()
}
static void Decrement(ref int baseValue, int step = 1)
{
for (int i = baseValue; i >= 0; i -= step)
{
Console.WriteLine(i);
}
}
CodePudding user response:
That's a good start, however, you are missing few key points here.
- You don not need a for loop inside your Decrement function. You have created nested loops which is not required.
- Also, you are counting till zero inside your for loop, hence baseValue will always be zero when it comes out of Decrement function.
- There is no need to break from your while loop. Unless someone enters a negative value.
- Use else if instead of if
Look at this code -
static void Main1(string[] args)
{
int initialTime = Convert.ToInt32(Console.ReadLine());
int remainingTime = initialTime;
while (remainingTime > 0)
{
if (remainingTime > 30)
{
Decrement(ref remainingTime, 10);
}
else if (remainingTime > 10)
{
Decrement(ref remainingTime, 5);
}
else
{
Decrement(ref remainingTime);
}
}
Console.Write("0\n");
Console.Read();
}
static void Decrement(ref int baseValue, int step = 1)
{
baseValue -= step;
Console.WriteLine(baseValue);
}
Also, add a negative value condition to this code.
CodePudding user response:
I suggest using enumeration: given baseValue
we return sequence IEnumerable<int>
:
public static IEnumerable<int> Decrement(int baseValue) {
for (int value = baseValue; value > 0; ) {
if (value > 30)
value -= 10;
else if (value > 10)
value -= 5;
else
value -= 1;
yield return value;
}
}
Then you can put
static void Main(string[] args) {
int initialTime = Convert.ToInt32(Console.ReadLine());
// Having enumeration, we can enumerate its items:
foreach (var time in Decrement(initialTime))
Console.WriteLine(time);
Console.Write("0\n");
Console.Read();
}
CodePudding user response:
The simplest way is to break the problem up into individual loops. There's no reason that it needs to be one loop:
static void main()
{
int initialTime = Convert.ToInt32(Console.ReadLine());
int remainingTime = initialTime;
while (remainingTime > 30 )
{
Console.WriteLine(remainingTime);
remainingTime -= 10;
}
while (remainingTime > 10 )
{
Console.WriteLine(remainingTime);
remainingTime -= 5;
}
while (remainingTime > 0 )
{
Console.WriteLine(remainingTime);
remainingTime -= 1;
}
Console.WriteLine(remainingTime);
}
However, having done that, you might notice that each of those loops looks... rather similar. You might notice that the only thing that changes is the terminating bound (30, 10, 0), and the decrement amount (10, 5, 1).
You can refactor it to remove the duplication in a couple of ways.
You could extract the loop into a shared method, thus:
static void main() { int initialTime = Convert.ToInt32(Console.ReadLine()); int remainingTime; remainingTime = countDown( initialTime, 10, 30 ) ; remainingTime = countDown( initialTime, 5, 10 ) ; remainingTime = countDown( initialTime, 1, 0 ) ; Console.WriteLine(remainingTime); } static int countDown( int time, int step, int bound ) { while ( time > step ) { Console.WriteLine(time); time -= step; } return time; }
You could collapse it to a single loop, thus:
static void main() { int initialTime = Convert.ToInt32(Console.ReadLine()); int remainingTime = initialTime; while ( remainingTime > 0 ) { int step = remainingTime > 30 ? 10 : remainingTime > 10 ? 5 : 1 ; Console.WriteLine(remainingTime); remainingTime -= step; } Console.WriteLine(remainingTime); }