Skip to content

Instantly share code, notes, and snippets.

@sarveshseri
Last active July 23, 2016 17:25
Show Gist options
  • Select an option

  • Save sarveshseri/5bf67bcaa52afd45eed5098f4f521d9d to your computer and use it in GitHub Desktop.

Select an option

Save sarveshseri/5bf67bcaa52afd45eed5098f4f521d9d to your computer and use it in GitHub Desktop.
import scala.collection.mutable.Stack
case class Tower(name: String, disks: Stack[Int])
case class TohState(src: String, tgt: String, tmp: String)
case class TohStep(move: String, before: TohState, after: TohState)
object LazyToh {
val srcName = "SRC"
val tgtName = "TGT"
val tmpName = "TMP"
def getTohStream(n: Int): Stream[TohStep] = {
val src = Tower(srcName, Stack[Int]().pushAll(Range(n, 0, -1)))
val tgt = Tower(tgtName, Stack[Int]())
val tmp = Tower(tmpName, Stack[Int]())
val initState = TohState(
s"[ $srcName ] :: " + src.disks.toString(),
s"[ $tgtName ] :: " +tgt.disks.toString(),
s"[ $tmpName ] :: " +tmp.disks.toString()
)
val initMove = s"Initialized TOH with $n disks"
val initStep = TohStep(initMove, initState, initState)
Stream(initStep) #::: getStreamOfMoves(n, src, tgt, tmp)
}
def getStreamOfMoves(n: Int, from: Tower, to: Tower, via: Tower): Stream[TohStep] = n match {
case 1 => {
println("------ DOING THE MOVE ------")
val towerMap: Map[String, Stack[Int]] = List(from, to, via).map(t => t.name -> t.disks)(collection.breakOut)
val beforeState = TohState(
towerMap.get(srcName).map(s"[ $srcName ] :: " + _.toString()).getOrElse("Invalid Stack"),
towerMap.get(tgtName).map(s"[ $tgtName ] :: " + _.toString()).getOrElse("Invalid Stack"),
towerMap.get(tmpName).map(s"[ $tmpName ] :: " + _.toString()).getOrElse("Invalid Stack")
)
val disk = from.disks.pop()
to.disks.push(disk)
val afterState = TohState(
towerMap.get(srcName).map(s"[ $srcName ] :: " + _.toString()).getOrElse("Invalid Stack"),
towerMap.get(tgtName).map(s"[ $tgtName ] :: " + _.toString()).getOrElse("Invalid Stack"),
towerMap.get(tmpName).map(s"[ $tmpName ] :: " + _.toString()).getOrElse("Invalid Stack")
)
val moveStr = s"Move disk [$disk] from ${from.name} to ${to.name}"
Stream(TohStep(moveStr, beforeState, afterState))
}
case x => {
getStreamOfMoves(n - 1, from, via, to) #::: getStreamOfMoves(1, from, to, via) #::: getStreamOfMoves(n - 1, via, to, from)
}
}
}
object LazyTohTest {
def main(args: Array[String]): Unit = {
val streamOfMoves = LazyToh.getTohStream(5)
streamOfMoves.take(3).foreach(tohStep => {
println("----------------------------")
println(s"${tohStep.before.src} |||| ${tohStep.before.tgt} |||| ${tohStep.before.tmp}")
println(tohStep.move)
println(s"${tohStep.after.src} |||| ${tohStep.after.tgt} |||| ${tohStep.after.tmp}")
println("----------------------------")
})
streamOfMoves.take(4).foreach(tohStep => {
println("----------------------------")
println(s"${tohStep.before.src} |||| ${tohStep.before.tgt} |||| ${tohStep.before.tmp}")
println(tohStep.move)
println(s"${tohStep.after.src} |||| ${tohStep.after.tgt} |||| ${tohStep.after.tmp}")
println("----------------------------")
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment