Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@swankjesse
Created January 12, 2020 16:00
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save swankjesse/8d1b53292f83820423466df86fb68ea1 to your computer and use it in GitHub Desktop.
Save swankjesse/8d1b53292f83820423466df86fb68ea1 to your computer and use it in GitHub Desktop.
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")
}
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