This one is just to scratch an itch, and probably not even a problem worth solving on it's own.
I'd like to write a recursive factorial function to print to the console in C#. The thing is, just out curiosity, I tried to get it to do this by only passing the function and argument. As in, I'd like to avoid having to type Console.WriteLine(Factorial(5));
It's harder that I'd thought to just type this and get a result:
> Factorial(5);
here is the function I've been playing with:
int Factorial(int number)
{
Console.Write(number != 1 ? $"{number} x " : $"{number} = \n");
if (number <= 1) return 1; // end of the line
number *= Factorial(number - 1); // recursive function
Console.WriteLine(number);
return number; // this could have been combined with line above, but more clear this way
}
the results come out like this, where instead of seeing the 2, 6 and 24. I'd just like to see the 120:
5 x 4 x 3 x 2 x 1 =
2
6
24
120
CodePudding user response:
Add an optional parameter to the function, indicating if it's an inner call, so the signature become
int Factorial(int number, bool inner=false)
outer call still use Factorial(5)
normally, but inside, change
number *= Factorial(number - 1);
to
number *= Factorial(number - 1, true);
then on printing the number, check if it's not inner, such as
if (!inner) Console.WriteLine(number);
CodePudding user response:
You could use a local function as the actual recursive part, using the outer Factorial function as a wrapper which just calls it!
int Factorial(int number)
{
static int DoFactorial(int number) => number <= 1
? 1
: number *= DoFactorial(number - 1);
var answer = DoFactorial(number);
Console.WriteLine(answer);
return answer;
}
CodePudding user response:
Performing side-effects inside a recursive function like calculating factorial is generally a terrible idea and what you are trying to do is something you really should not.
Get the answer, and then print it out in the calling code.
That said, here is a horrible way to achieve what you asked for. Please do not do this, I only offer this answer to show it is possible.
using System;
using System.Diagnostics;
namespace Test
{
public static class Program
{
static void Main(string[] args)
{
var stackTrace = new StackTrace();
var frames = stackTrace.GetFrames();
Factorial(5, frames.Length);
}
static int Factorial(int number, int frameCount)
{
Console.Write(number != 1 ? $"{number} x " : $"{number} = \n");
if (number <= 1)
{
return 1; // end of the line
}
number *= Factorial(number - 1, frameCount); // recursive function
var stackTrace = new StackTrace();
var frames = stackTrace.GetFrames();
if (frames.Length == frameCount 1)
{
Console.WriteLine(number);
}
return number; // this could have been combined with line above, but more clear this way
}
}
}