Skip to content

Instantly share code, notes, and snippets.

@divyang4481
Last active March 23, 2020 04:54
Show Gist options
  • Select an option

  • Save divyang4481/e1f625abfd5258efd310f4dc2c6bb625 to your computer and use it in GitHub Desktop.

Select an option

Save divyang4481/e1f625abfd5258efd310f4dc2c6bb625 to your computer and use it in GitHub Desktop.
Trampolining
public sealed class Bounce<T1, T2, TResult>
{
public T1 Arg1 { get; private set; }
public T2 Arg2 { get; private set; }
public TResult Result { get; private set; }
public bool HasResult { get; private set; }
private Bounce() { }
public static Bounce<T1, T2, TResult> Continue(T1 arg1, T2 arg2)
{
return new Bounce<T1, T2, TResult>()
{
Arg1 = arg1,
Arg2 = arg2
};
}
public static Bounce<T1, T2, TResult> End(TResult result)
{
return new Bounce<T1, T2, TResult>()
{
Result = result,
HasResult = true
};
}
}
public class Client
{
public BigInt factorial(BigInt n)
{
return Trampoline.Start<BigInt, BigInt, BigInt>(iteration, 1, n);
}
private Bounce<BigInt, BigInt, BigInt> iteration(BigInt current, BigInt n)
{
return n == 0 ? Bounce<BigInt, BigInt, BigInt>.End(current) :
Bounce<BigInt, BigInt, BigInt>.Continue(current * n, n - 1);
}
}
public static class Trampoline
{
public static TResult Start<T1, T2, TResult>(Func<T1, T2, Bounce<T1, T2, TResult>> action,
T1 arg1, T2 arg2)
{
TResult result = default(TResult);
Bounce<T1, T2, TResult> bounce = Bounce<T1, T2, TResult>.Continue(arg1, arg2);
while (true)
{
if (bounce.HasResult)
{
result = bounce.Result;
break;
}
bounce = action(bounce.Arg1, bounce.Arg2);
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment