Skip to content

Instantly share code, notes, and snippets.

@pakaufmann
Created December 24, 2016 09:33
Show Gist options
  • Save pakaufmann/33aa8cd79d44e6c2ed022524de1b599d to your computer and use it in GitHub Desktop.
Save pakaufmann/33aa8cd79d44e6c2ed022524de1b599d to your computer and use it in GitHub Desktop.
object Day24 extends Challenge {
override def runFirst(): Unit = {
val map = createMap(loadFile("day24.txt").getLines().toSeq)
val destinations = map.filter(_._2 >= 2).keys
val start = map.find(_._2 == 2).get._1
val lengths = destinations.flatMap { destination =>
val others = destinations.filterNot(_ == destination)
others.map(o => (destination, o) -> findShortestPath(destination, o, map))
}.toMap
val permutations = destinations.toList.permutations.toList.filter(_.head != start)
val minLength = permutations.map { p =>
p.sliding(2).foldLeft(0) {
case (l, Seq(from, to)) =>
l + lengths(from, to)
}
}.min
println(minLength)
}
override def runSecond(): Unit = {
val map = createMap(loadFile("day24.txt").getLines().toSeq)
val destinations = map.filter(_._2 >= 2).keys
val start = map.find(_._2 == 2).get._1
val lengths = destinations.flatMap { destination =>
val others = destinations.filterNot(_ == destination)
others.map(o => (destination, o) -> findShortestPath(destination, o, map))
}.toMap
val permutations = destinations.toList.permutations.toList.filter(_.head != start)
val minLength = permutations.map { p =>
(p :+ p.head).sliding(2).foldLeft(0) {
case (l, Seq(from, to)) =>
l + lengths(from, to)
}
}.min
println(minLength)
}
private def findShortestPath(start: (Int, Int), end: (Int, Int), map: Map[(Int, Int), Int]): Int = {
val open = Set(start -> 0)
val a = Iterator
.iterate(open -> Set.empty[(Int, Int)]) {
case (open, closed) =>
val newOpen = open.flatMap {
case (f, step) =>
Set(
f.copy(_1 = f._1 - 1) -> (step + 1),
f.copy(_1 = f._1 + 1) -> (step + 1),
f.copy(_2 = f._2 - 1) -> (step + 1),
f.copy(_2 = f._2 + 1) -> (step + 1)
)
}.filterNot(o => closed.contains(o._1) || map(o._1) == 0)
(newOpen, closed ++ open.map(_._1))
}
.dropWhile(!_._1.exists(_._1 == end))
.take(1)
.toList
.head
._1
.find(_._1 == end)
val b = a.get._2
b
}
private def createMap(lines: Seq[String]): Map[(Int, Int), Int] = {
val map = Map.empty[(Int, Int), Int]
lines.zipWithIndex.foldLeft(map) {
case (map2, (line, x)) =>
line.split("").zipWithIndex.foldLeft(map2) {
case (map3, (field, y)) =>
map3 + ((x -> y) -> (field match {
case "#" => 0
case "." => 1
case d => d.toInt + 2
}))
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment