123 lines
3.5 KiB
Kotlin
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()
|
|
}
|