Created
January 12, 2020 16:00
-
-
Save swankjesse/8d1b53292f83820423466df86fb68ea1 to your computer and use it in GitHub Desktop.
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
import java.math.BigInteger | |
interface Fibonacci { | |
fun fib(n: Int): Int | |
} | |
object LawfulGood : Fibonacci { | |
override fun fib(n: Int): Int { | |
check(n >= 0) { "fib is undefined for negative values: $n" } | |
return when (n) { | |
0 -> 0 | |
1, 2 -> 1 | |
else -> { | |
val resultLong = fib(n - 1).toLong() + fib(n - 2).toLong() | |
val resultInt = resultLong.toInt() | |
check(resultInt.toLong() == resultLong) { "fib is not an Int: $n" } | |
resultInt | |
} | |
} | |
} | |
} | |
object LawfulNeutral : Fibonacci { | |
override fun fib(n: Int): Int { | |
return fib(n.toBigInteger()).toInt() | |
} | |
fun fib(n: BigInteger): BigInteger { | |
return when (n) { | |
BigInteger.ONE, BigInteger.TWO -> BigInteger.ONE | |
else -> fib(n.subtract(BigInteger.ONE)) + fib(n.subtract(BigInteger.TWO)) | |
} | |
} | |
} | |
object NeutralGood : Fibonacci { | |
override fun fib(n: Int): Int { | |
var a = 1 | |
var b = 1 | |
for (i in 2 until n) { | |
val c = a + b | |
a = b | |
b = c | |
} | |
return b | |
} | |
} | |
object TrueNeutral : Fibonacci { | |
override fun fib(n: Int): Int { | |
return when (n) { | |
1, 2 -> 1 | |
else -> fib(n - 1) + fib(n - 2) | |
} | |
} | |
} | |
object NeutralEvil : Fibonacci { | |
override fun fib(n: Int): Int = if (n < 3) 1 else fib(n - 1) + fib(n - 2) | |
} | |
object ChaoticGood : Fibonacci { | |
override fun fib(n: Int) = fibonacci(n) | |
tailrec fun fibonacci(n: Int, a: Int = 1, b: Int = 1): Int { | |
return when { | |
n < 3 -> b | |
else -> fibonacci(n - 1, b, a + b) | |
} | |
} | |
} | |
object ChaoticNeutral : Fibonacci { | |
override fun fib(n: Int) = when (n) { | |
1 -> 1; 2 -> 1; 3 -> 2; 4 -> 3; 5 -> 5; 6 -> 8; 7 -> 13; 8 -> 21; 9 -> 34; 10 -> 55; 11 -> 89 | |
12 -> 144; 13 -> 233; 14 -> 377; 15 -> 610; 16 -> 987; 17 -> 1597; 18 -> 2584; 19 -> 4181 | |
20 -> 6765; 21 -> 10946; 22 -> 17711; 23 -> 28657; 24 -> 46368; 25 -> 75025; 26 -> 121393 | |
27 -> 196418; 28 -> 317811; 29 -> 514229; 30 -> 832040; 31 -> 1346269; 32 -> 2178309 | |
33 -> 3524578; 34 -> 5702887; 35 -> 9227465; 36 -> 14930352; 37 -> 24157817; 38 -> 39088169 | |
39 -> 63245986; 40 -> 102334155; 41 -> 165580141; 42 -> 267914296; 43 -> 433494437 | |
44 -> 701408733; 45 -> 1134903170; 46 -> 1836311903 | |
else -> error("fib($n) is not an Int") | |
} | |
} | |
object ChaoticEvil : Fibonacci { | |
override fun fib(n: Int) = n.x3e.length | |
val Int.x3e: String | |
get() { | |
var x3e = this + "${-0x3e}".length - ("0x3e").length | |
return if ("${x3e and 0x3e}" > "0x3e") "${x3e--.x3e}${x3e.x3e}" else ("\u003e") | |
} | |
} | |
fun main() { | |
check(LawfulGood) | |
check(LawfulNeutral) | |
check(LawfulEvil()) | |
check(NeutralGood) | |
check(TrueNeutral) | |
check(NeutralEvil) | |
check(ChaoticNeutral) | |
check(ChaoticGood) | |
check(ChaoticEvil) | |
} | |
fun check(fibonacci: Fibonacci) { | |
check(fibonacci.fib(1) == 1) | |
check(fibonacci.fib(2) == 1) | |
check(fibonacci.fib(3) == 2) | |
check(fibonacci.fib(4) == 3) | |
check(fibonacci.fib(5) == 5) | |
check(fibonacci.fib(6) == 8) | |
check(fibonacci.fib(7) == 13) | |
check(fibonacci.fib(8) == 21) | |
println("VALID: $fibonacci") | |
} |
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 LawfulEvil implements Fibonacci { | |
@Override | |
public int fib(int n) { | |
if (n == 1 || n == 2) return 1; | |
return fib(n - 1) + fib(n - 2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment