Last active
March 23, 2020 04:54
-
-
Save divyang4481/e1f625abfd5258efd310f4dc2c6bb625 to your computer and use it in GitHub Desktop.
Trampolining
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| }; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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