1

I have this code that gets an input from the user and calculate its factorial and the factorial for less than the input number, but I keep getting the factorial for the first number only and the rest is 0. It should be like this: For example, if the input is 5:

5! = 120

4! = 24

3! = 6

2! = 4

1! = 1

How do I make the loop go throw all the numbers below the input number?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace multiple_factorials
{
    class Program
    {
        static void Main(string[] args)
        {
            int num, n;

            Console.WriteLine(".....................[Application 1].....................\n\n");
            Console.WriteLine("Please enter a number to get its factorial: ");
            num = Convert.ToInt32(Console.ReadLine());

            n = num; // Assign n to num

            while (num > 0)
            {
                for (int i = n - 1; i > 0; i--)
                {
                   n *= i;
                }
                Console.WriteLine("Factorial of {0}! = {1}\n", num, n);
                num--;
            }
        }
    }
}
Dmitry Bychenko
  • 165,109
  • 17
  • 150
  • 199
Ahmad Khalil
  • 179
  • 1
  • 4
  • 14

6 Answers6

7

You've included System.Linq so I've put a LINQ solution:

 int n = 5;

 // result == 120
 int result = Enumerable.Range(1, n).Aggregate(1, (p, item) => p * item);

However, LINQ is overkill here, and the for loop is more readable. To print out all the lines:

int num = 5;

String result = String.Join(Environment.NewLine,
  Enumerable.Range(1, num)
    .Reverse()
    .Select((index) =>
      String.Format("Factorial of {0}! = {1}\n",
                    index,
                    Enumerable.Range(1, index).Aggregate(1, (p, item) => p * item))));

Console.Write(result);
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Dmitry Bychenko
  • 165,109
  • 17
  • 150
  • 199
  • _"You've included System.Linq so I've put a LINQ solution:"_ - just so you know Visual Studio automatically adds `using System.Linq` to the top of new classes and more importantly when creating a _console app_ – MickyD Jun 24 '21 at 04:38
6

Just move n = num; inside the while loop:

while (num > 0)
{
    n = num;
    for (int i = n - 1; i > 0; i--)
    {
        n *= i;
    }
    Console.WriteLine("Factorial of {0}! = {1}\n", num, n);
    num--;
}
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Ahmad Khalil
  • 179
  • 1
  • 4
  • 14
3

To answer you question now you have acctually posted it:

My question is How to make the loop go throw all the numbers below the input number?

With a loop

for(int i = input; i > 0; i--)

Will count down from input (lets say 5) to 1 {5, 4, 3, 2, 1}

then you simply multiply together

int result = 1;
for(int i = input; i > 0; i--) 
    result *= i; 

Proof: int input = 4; int result = 1; for(int i = input; i > 0; i--) result *= i;

Console.WriteLine("Result=" + result);

Output: 24

A better way Using Recusion

public int Factorial(int f)
{
    if(f == 0)
        return 1;
    else
        return f * Factorial(f-1); 
}

so calling Factorial(5) gives a result of 120 etc.

Alex Anderson
  • 752
  • 3
  • 10
  • Clearly this does not answer the question but get all the votes – Eric Mar 13 '15 at 07:49
  • 1
    It does now Eric, i answered before OP acctually posted a question. His OP was just "Here is code". – Alex Anderson Mar 13 '15 at 07:51
  • the answer is as Eric said : just move n=num; inside the while loop and it works. ( Solved ) – Ahmad Khalil Mar 13 '15 at 07:58
  • 1
    Two things. First, the validation should be if it is less than 2. The second, use long instead of int. For example, for Factorial (13) it returns an incorrect value. – Sith2021 Aug 19 '21 at 23:39
2

As a definition, 0! == 1. There are several ways to deal with this, from the shortest to the most clever, so that you get the sequence: 1, 1, 2, 6, 24, 120... I think that Linq gives the shortest/cleanest code.

int f(i) => Enumerable.Range(1,i<1?1:i).Aggregate((f,x)=>f*x);

Other alternatives, tho less clean, wouold be:

int f(i) => Enumerable.Range(1,Math.Max(1,i).Aggregate((f,x)=>f*x);

int f(i) => Enumerable.Range(1,i+(int)Math.Pow(0,i)).Aggregate((f,x)=>f*x);
Zuabros
  • 236
  • 1
  • 5
  • 3
    I mean, if brevity over performance is the goal, then _technically_ `Enumerable.Range(1,++i).Aggregate((f,x)=>f*x)/i;` is shorter. (Please don't ever do this). – Hod - Monica's Army Feb 18 '21 at 18:09
1

Two things;

Change your int i = n - 1 to int i = num and assign your n to 1 just before your for loop.

while (num > 0)
{
     n = 1;
     for (int i = num; i > 0; i--)
     {                    
           n *= i;
     }           
     Console.WriteLine("Factorial of {0}! = {1}\n", num, n);
     num--;
}

Result will be;

Please Enter A Number To Get Its factorial 5

Factorial of 5! = 120

Factorial of 4! = 24

Factorial of 3! = 6

Factorial of 2! = 2

Factorial of 1! = 1

Soner Gönül
  • 94,086
  • 102
  • 195
  • 339
0

You can use recursive function for factorial calculation sample code is:

public static int  fak(int number)
{
    if(number==1)
    {
        return 1;
    }
    else
    {
        return number*(fak(number-1));
    }
}