Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Instant Insanity in Scala
object InstantInsanity extends App {
type Cube = Seq[Char]
val cubes: Seq[Cube] = Seq("BGWGBR", "WGBWRR", "GWRBRR", "BRGGWW").map(_.toSeq)
// Rotate a cube 90 degrees over its Z-axis, leaving up and down in place.
def rot: Cube => Cube = { case Seq(u, f, r, b, l, d) => Seq(u, r, b, l, f, d) }
// Twist a cube around the axis running from the upper-front-right
// corner to the back-left-down corner.
def twist: Cube => Cube = { case Seq(u, f, r, b, l, d) => Seq(f, r, u, l, d, b) }
// Exchange up and down, front and left, back and right.
def flip: Cube => Cube = { case Seq(u, f, r, b, l, d) => Seq(d, l, b, r, f, u) }
// Compute all 24 ways to orient a cube.
def orientations: Cube => Seq[Cube] = { c: Cube =>
for {
c1 <- Seq(c, rot(c), rot(rot(c)), rot(rot(rot(c))))
c2 <- Seq(c1, twist(c1), twist(twist(c1)))
c3 <- Seq(c2, flip(c2))
} yield c3
}
// Compute which faces of a cube are visible when placed in a pile.
def visible: Cube => Seq[Char] = { case Seq(u, f, r, b, l, d) => Seq(f, r, b, l) }
// Two cubes are compatible if they have different colours on every
// visible face.
def compatible: (Cube, Cube) => Boolean = {
case (c1, c2) => visible(c1).zip(visible(c2)).forall { case (v1, v2) => v1 != v2 }
}
// Determine whether a cube can be added to pile of cubes, without
// invalidating the solution.
def allowed: (Cube, Seq[Cube]) => Boolean = {
case (c, cs) => cs.forall(compatible(_, c))
}
// Return a list of all ways of orienting each cube such that no side of
// the pile has two faces the same.
def solutions: Seq[Cube] => Seq[Seq[Cube]] = {
case Nil => Seq(Nil)
case c :: cs => for {
_cs <- solutions(cs)
_c <- orientations(c)
if allowed(_c, _cs)
} yield _c +: _cs
}
solutions(cubes)
.map(_.map(_.mkString("")))
.map(ss => "[" + ss.mkString(", ") + "]")
.foreach(println)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.