123 lines
3.5 KiB
Kotlin

package aoc2023
import lcm
import println
import readInput
/*
--- Day 8: Haunted Wasteland ---
https://adventofcode.com/2023/day/8
*/
fun main() {
val inlineTestInput = """
RL
AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
EEE = (EEE, EEE)
GGG = (GGG, GGG)
ZZZ = (ZZZ, ZZZ)
"""
val inlineTestInput2 = """
LR
ABA = (ABB, XXX)
ABB = (XXX, ABZ)
ABZ = (ABB, XXX)
BAA = (BAB, XXX)
BAB = (BAC, BAC)
BAC = (BAZ, BAZ)
BAZ = (BAB, BAB)
XXX = (XXX, XXX)
"""
fun part1(input: List<String>): Int {
val cmd = input[0]
val map = HashMap<String, Pair<String, String>>()
for (i in input.drop(2)) {
"([A-Z][A-Z][A-Z]) = .([A-Z][A-Z][A-Z]), ([A-Z][A-Z][A-Z]).".toRegex().matchEntire(i)!!.destructured
.let { (id, left, right) -> map[id] = left to right }
}
var instPos = 0
var steps = 0
var loc = "AAA"
do {
loc = if (cmd[instPos] == 'L') map[loc]!!.first else map[loc]!!.second
instPos = (instPos + 1) % cmd.length
steps++
} while (loc != "ZZZ")
return steps
}
fun part2(input: List<String>): Long {
val cmd = input[0]
val map = HashMap<String, Pair<String, String>>()
for (i in input.drop(2)) {
"([A-Z][A-Z][A-Z]) = .([A-Z][A-Z][A-Z]), ([A-Z][A-Z][A-Z]).".toRegex().matchEntire(i)!!.destructured
.let { (id, left, right) -> map[id] = left to right }
}
val starts = map.keys.filter { it.endsWith("A") }
var ggts = HashSet<Int>()
for (start in starts) {
var instPos = 0
var steps = 0
var loc = start
do {
loc = if (cmd[instPos] == 'L') map[loc]!!.first else map[loc]!!.second
instPos = (instPos + 1) % cmd.length
steps++
} while (!loc.endsWith("Z"))
ggts.add(steps)
}
return ggts.map(Int::toLong).lcm()
// val primes = ArrayList<Int>()
// val factors = HashSet<Int>()
// var prime = 2
// primes.add(2)
// do {
// val newGgts = HashSet<Int>()
// for (f in ggts) {
// if (prime * 2 - 1 > f) {
// factors.add(f)
// } else {
// if (f % prime == 0) {
// newGgts.add(f / prime)
// factors.add(prime)
// } else {
// newGgts.add(f)
// }
// }
// }
// ggts = newGgts
// if (prime == 2) {
// prime = 3
// } else {
// do {
// prime += 2
// } while (primes.any { (prime % it) == 0 })
// }
// primes.add(prime)
// } while (ggts.isNotEmpty())
//
// return factors.map { it.toLong() }.reduce(Long::times)
}
// test if implementation meets criteria from the description, like:
val testInput = inlineTestInput.trim().reader().readLines()
val testInput2 = inlineTestInput2.trim().reader().readLines()
//val testInput = readInput("aoc2023/Day08_test")
val testInputPart1Result = part1(testInput)
println("Part 1 Test: $testInputPart1Result")
val testInputPart2Result = part2(testInput2)
println("Part 2 Test: $testInputPart2Result")
check(testInputPart1Result == 2)
check(testInputPart2Result == 6L)
val input = readInput("aoc2023/Day08")
part1(input).println()
part2(input).println()
}