Skip to content

Instantly share code, notes, and snippets.

@ElectricCoffee
Last active August 29, 2015 14:03
Show Gist options
  • Save ElectricCoffee/1d5ae8b4359ddbc9eefb to your computer and use it in GitHub Desktop.
Save ElectricCoffee/1d5ae8b4359ddbc9eefb to your computer and use it in GitHub Desktop.
An attempt to calculate Ackermann in Scala... It keeps overflowing the stack near Ack(3,11)
package io.wausoft
import org.joda.time.{Seconds, DateTime}
import scala.collection.mutable
case class Ack(m: Int, n: Int)
object Program extends App {
// Basic ackermann without cache, overflows at around Ack(3,11) after a few seconds
def compute(a: Ack): Int = a match {
case Ack(0, n) => n + 1
case Ack(m, 0) => compute(Ack(m - 1, 1))
case Ack(m, n) => compute(Ack(m - 1, compute(Ack(m, n - 1))))
}
// ackermann with cache, overflows at around Ack(3,11) instantly
def computeWithCache(a: Ack, cache: mutable.Map[Ack, Int]): Int = if(cache contains a) {
val res = cache(a)
println(s"result from cache: $res")
return res // explicit 'return' for readability
} else {
val res = a match {
case Ack(0, n) => n + 1
case Ack(m, 0) => computeWithCache(Ack(m - 1, 1), cache)
case Ack(m, n) => computeWithCache(Ack(m - 1, computeWithCache(Ack(m, n - 1), cache)), cache)
}
cache += a -> res
return res
}
// convenience method
def getSeconds(start: DateTime, end: DateTime): Int = Seconds.secondsBetween(start, end).getSeconds
val time = DateTime.now
val cache = mutable.Map[Ack, Int]()
for{ i <- 0 to 4
j <- 0 until 20
} println(s"result of ackermann($i, $j) => ${computeWithCache(Ack(i, j), cache)}. Time: ${getSeconds(time, DateTime.now)}")
}
name := "Ackermann"
version := "1.0"
libraryDependencies ++= Seq( "joda-time" % "joda-time" % "2.3"
, "org.joda" % "joda-convert" % "1.6"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment