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): Int { val cmd = input[0] val map = HashMap>() 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): Long { val cmd = input[0] val map = HashMap>() 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() 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() // val factors = HashSet() // var prime = 2 // primes.add(2) // do { // val newGgts = HashSet() // 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() }