aoc2023/src/day08.scala
Paul-Henri Froidmont 80c6e406c7
Day 08
2023-12-08 14:22:06 +01:00

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