Home > Enterprise >  Program that counting down by 10, 5, and 1
Program that counting down by 10, 5, and 1

Time:11-05

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.

  1. You don not need a for loop inside your Decrement function. You have created nested loops which is not required.
  2. Also, you are counting till zero inside your for loop, hence baseValue will always be zero when it comes out of Decrement function.
  3. There is no need to break from your while loop. Unless someone enters a negative value.
  4. 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);
    
    }
    
  •  Tags:  
  • c#
  • Related