Skip to content

Instantly share code, notes, and snippets.

@tmatz
Last active March 31, 2019 11:53
Show Gist options
  • Save tmatz/73321b23b6af5b0cc23efdbc0226fad2 to your computer and use it in GitHub Desktop.
Save tmatz/73321b23b6af5b0cc23efdbc0226fad2 to your computer and use it in GitHub Desktop.
// Trampoline:
// Tail recursion optimization technique.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
namespace SoloLearn
{
class Program
{
static void Main(string[] args)
{
WriteLine($"5! = {Factorial(5)}");
WriteLine($"5! = {TrampolineFactorial(5)}");
}
static int
Factorial(int n, int m = 1)
=> (n < 2) ?
m :
Factorial(n - 1, m * n);
static int
TrampolineFactorial(int n)
{
Bounce<int>
Factorial(int nn, int m = 1)
=> (nn < 2) ?
Trampoline.Done(() => m) :
Trampoline.Next(() => Factorial(nn - 1, m * nn));
return Factorial(n).Evaluate();
}
}
static class Trampoline
{
public static Bounce<T>
Done<T>(Func<T> done)
=> new Bounce<T>(done, null);
public static Bounce<T>
Next<T>(Func<Bounce<T>> next)
=> new Bounce<T>(null, next);
}
struct Bounce<T>
{
Func<T> Done { get; }
Func<Bounce<T>> Next { get; }
internal Bounce(Func<T> done, Func<Bounce<T>> next)
=> (Done, Next) = (done, next);
public T Evaluate()
{
var bounce = this;
while (bounce.Done == null)
{
bounce = bounce.Next();
}
return bounce.Done();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment