diff --git a/src/main/kotlin/no/rodland/advent_2023/Day08.kt b/src/main/kotlin/no/rodland/advent_2023/Day08.kt index a53dc897..6e56ba96 100644 --- a/src/main/kotlin/no/rodland/advent_2023/Day08.kt +++ b/src/main/kotlin/no/rodland/advent_2023/Day08.kt @@ -3,20 +3,19 @@ package no.rodland.advent_2023 import no.rodland.advent.Day import no.rodland.advent.cycle import java.math.BigInteger -import java.util.* // template generated: 08/12/2023 // Fredrik Rødland 2023 -class Day08(val input: List) : Day>> { +class Day08(val input: List) : Day>> { private val parsed = input.parse() - override fun partOne(): Long { + override fun partOne(): BigInteger { val (instructions, places) = parsed return find(listOf("AAA"), places, instructions) } - override fun partTwo(): Long { + override fun partTwo(): BigInteger { val (instructions, places) = parsed val start = places.filterKeys { it.endsWith("A") }.keys.toList() return find(start, places, instructions) @@ -26,52 +25,33 @@ class Day08(val input: List) : Day, places: Map, instructions: Instructions - ): Long { + ): BigInteger { val periods = start - .map { - dfs(it, places = places, instructions = instructions) - } + .map { traverse(it, places = places, instructions = instructions) } .map { BigInteger.valueOf(it) } - return periods.reduce { acc, i -> - lcm(acc, i) - }.toLong() + return periods.reduce { acc, i -> lcm(acc, i) } } private fun lcm(n1: BigInteger, n2: BigInteger): BigInteger { // https://no.wikipedia.org/wiki/Minste_felles_multiplum // lcm = (n1 * n2) / gcd - val gcd = n1.gcd(n2) - return ((n1 * n2) / gcd) + return (n1 * n2) / n1.gcd(n2) } data class State(val id: String, val pos: Int) - private fun dfs( - startId: String, - places: Map, - instructions: Instructions - ): Long { + private fun traverse(startId: String, places: Map, instructions: Instructions): Long { var seenCount = 0L - val stack = Stack() - val pos = instructions.pos() - stack.push(State(startId, pos)) - while (stack.isNotEmpty()) { - val (id, _) = stack.pop() + var id = startId + for (dir in instructions) { + seenCount++ + val nextPlaces = places[id]!! + id = if (dir == Dir.L) nextPlaces.left else nextPlaces.right if (id.endsWith("Z")) { return seenCount } - val nextPlaces = places[id] ?: error("hm - why don't we have place $id") - // If this state has been visited before, skip - // if (!visited.add(State(id, instructions.pos()))) { println("SEEN"); continue } - // println("A PLACE: $nextPlaces $ids") - - val nextDir = instructions.next() - val nextIds = if (nextDir == Dir.L) nextPlaces.left else nextPlaces.right - val nextPos = instructions.pos() - stack.push(State(nextIds, nextPos)) - seenCount++ } - return seenCount + error("Endstate not found") } enum class Dir { L, R } diff --git a/src/test/kotlin/no/rodland/advent_2023/Day08Test.kt b/src/test/kotlin/no/rodland/advent_2023/Day08Test.kt index 486bd930..b8682468 100644 --- a/src/test/kotlin/no/rodland/advent_2023/Day08Test.kt +++ b/src/test/kotlin/no/rodland/advent_2023/Day08Test.kt @@ -4,6 +4,7 @@ import no.rodland.advent.* import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import readFile +import java.math.BigInteger @Suppress("ClassName", "PrivatePropertyName") @DisableSlow @@ -40,10 +41,10 @@ internal class Day08Test { "ZZZ = (ZZZ, ZZZ)", ) - private val resultTestOne = 2L - private val resultTestTwo = 2L - private val resultOne = 18827L - private val resultTwo = 20220305520997L + private val resultTestOne = BigInteger.valueOf(2L) + private val resultTestTwo = BigInteger.valueOf(2L) + private val resultOne = BigInteger.valueOf(18827) + private val resultTwo = BigInteger.valueOf(20220305520997L) val test = defaultTestSuiteParseOnInit( Day08(data08), @@ -81,7 +82,7 @@ internal class Day08Test { @Test fun `08,1,test,2`() { val day = Day08(test08_2) - report(test.testPart1.copy(function = { day.partOne() }, expected = 6L)) + report(test.testPart1.copy(function = { day.partOne() }, expected = BigInteger.valueOf(6L))) } @Test @@ -95,7 +96,7 @@ internal class Day08Test { @Test fun `08,2,test`() { val day08 = Day08(test08_3) - report(AOCTest({ day08.partTwo() }, Unit, 6L, 1, day08.day, Part.TWO, false)) + report(AOCTest({ day08.partTwo() }, Unit, BigInteger.valueOf(6), 1, day08.day, Part.TWO, false)) } @Test