54 lines
1.3 KiB
Scala
54 lines
1.3 KiB
Scala
package aoc
|
|
package day08
|
|
|
|
import scala.annotation.tailrec
|
|
|
|
val dayNumber = "08"
|
|
|
|
@main def part1: Unit =
|
|
println(part1(loadInput(dayNumber)))
|
|
|
|
@main def part2: Unit =
|
|
println(part2(loadInput(dayNumber)))
|
|
|
|
def findPathLength(
|
|
nodeMap: Map[String, (String, String)],
|
|
instructions: String,
|
|
startNode: String,
|
|
endNode: String => Boolean
|
|
): Long =
|
|
LazyList
|
|
.continually(instructions)
|
|
.flatMap(_.toSeq)
|
|
.scanLeft(startNode) {
|
|
case (node, 'L') => nodeMap(node)._1
|
|
case (node, 'R') => nodeMap(node)._2
|
|
}
|
|
.takeWhile(!endNode(_))
|
|
.length
|
|
|
|
def part1(input: String) =
|
|
val Array(instructions, nodesStr) = input.split("\n\n")
|
|
val nodeMap = nodesStr
|
|
.split('\n')
|
|
.map { case s"$name = ($left, $right)" => (name, (left, right)) }
|
|
.toMap
|
|
findPathLength(nodeMap, instructions, "AAA", _ == "ZZZ").toString
|
|
|
|
def part2(input: String) =
|
|
val Array(instructions, nodesStr) = input.split("\n\n")
|
|
val nodeMap = nodesStr
|
|
.split('\n')
|
|
.map { case s"$name = ($left, $right)" => (name, (left, right)) }
|
|
.toMap
|
|
|
|
@tailrec def gcd(a: Long, b: Long): Long =
|
|
if (b == 0) a.abs else gcd(b, a % b)
|
|
def lcm(a: Long, b: Long) =
|
|
(a * b).abs / gcd(a, b)
|
|
|
|
nodeMap.keySet
|
|
.filter(_.endsWith("A"))
|
|
.map(node => findPathLength(nodeMap, instructions, node, _.endsWith("Z")))
|
|
.reduce(lcm)
|
|
.toString
|