static RecursionResult <BigInteger> Factorial(int n, BigInteger product)
 {
     if (n < 2)
     {
         return(TailRecursion.Return(product));
     }
     return(TailRecursion.Next(() => Factorial(n - 1, n * product)));
 }
        public void Factorial_should_return_same_result_for_all_implementations(int n)
        {
            var basicResult      = BasicRecursion.Factorial(n);
            var tailResult       = TailRecursion.Factorial(n);
            var iterrativeResult = Iterative.Factorial(n);
            var enumerableResult = Enumerable.Factorial(n);

            Assert.That(basicResult, Is.EqualTo(tailResult));
            Assert.That(basicResult, Is.EqualTo(iterrativeResult));
            Assert.That(basicResult, Is.EqualTo(enumerableResult));
        }
예제 #3
0
        public void Returns_final_result_after_recursion()
        {
            RecursionResult <int> Factorial(int k)
            {
                RecursionResult <int> FactorialAcc(int m, int acc)
                {
                    if (m == 1)
                    {
                        return(RecursionResult <int> .Final(acc));
                    }

                    return(RecursionResult <int> .Next(() => FactorialAcc(m - 1, m *acc)));
                }

                return(FactorialAcc(k, 1));
            }

            Assert.Equal(5 * 4 * 3 * 2 * 1, TailRecursion.Run(() => Factorial(5)));
        }
예제 #4
0
        public void Deep_recursion_does_not_blow_the_stack()
        {
            RecursionResult <BigInteger> Factorial(int k)
            {
                RecursionResult <BigInteger> FactorialAcc(int m, BigInteger acc)
                {
                    if (m == 1)
                    {
                        return(RecursionResult <BigInteger> .Final(acc));
                    }

                    return(RecursionResult <BigInteger> .Next(() => FactorialAcc(m - 1, m *acc)));
                }

                return(FactorialAcc(k, 1));
            }

            var ex = Record.Exception(() => TailRecursion.Run(() => Factorial(20000)));

            Assert.Null(ex);
        }
 static void Main(string[] args)
 {
     BigInteger result = TailRecursion.Execute(() => Factorial(50000, 1));
 }
예제 #6
0
 public int TailRecursionTest()
 {
     return(TailRecursion.Factorial(N));
 }
예제 #7
0
        public BigInteger FactorialTrampoline(int x)
        {
            BigInteger result = TailRecursion.Execute(() => Factorial(x, 1));

            return(result);
        }
예제 #8
0
        public void Returns_final_result()
        {
            RecursionResult <int> F() => RecursionResult <int> .Final(1);

            Assert.Equal(1, TailRecursion.Run(F));
        }
예제 #9
0
        public void Returns_final_result_from_next_iteration()
        {
            RecursionResult <int> F() => RecursionResult <int> .Next(() => RecursionResult <int> .Final(2));

            Assert.Equal(2, TailRecursion.Run(F));
        }