Day 21 :-(
This commit is contained in:
parent
aa0f1dad74
commit
f494b763cf
141
src/aoc2024/Day21.kt
Normal file
141
src/aoc2024/Day21.kt
Normal file
@ -0,0 +1,141 @@
|
||||
package aoc2024
|
||||
|
||||
import RelPos
|
||||
import println
|
||||
import readInput
|
||||
|
||||
/*
|
||||
--- Day 21: Keypad Conundrum ---
|
||||
https://adventofcode.com/2024/day/21
|
||||
*/
|
||||
fun main() {
|
||||
|
||||
val inlineTestInput = """
|
||||
029A
|
||||
980A
|
||||
179A
|
||||
456A
|
||||
379A
|
||||
"""
|
||||
|
||||
val doorPadMap = hashMapOf(
|
||||
'7' to RelPos(-2, -3),
|
||||
'8' to RelPos(-1, -3),
|
||||
'9' to RelPos(0, -3),
|
||||
'4' to RelPos(-2, -2),
|
||||
'5' to RelPos(-1, -2),
|
||||
'6' to RelPos(0, -2),
|
||||
'1' to RelPos(-2, -1),
|
||||
'2' to RelPos(-1, -1),
|
||||
'3' to RelPos(0, -1),
|
||||
'0' to RelPos(-1, 0),
|
||||
'A' to RelPos(0, 0),
|
||||
)
|
||||
|
||||
val robotPadMap = hashMapOf(
|
||||
'^' to RelPos(-1, 0),
|
||||
'A' to RelPos(0, 0),
|
||||
'<' to RelPos(-2, 1),
|
||||
'v' to RelPos(-1, 1),
|
||||
'>' to RelPos(0, 1),
|
||||
)
|
||||
|
||||
data class PadState(
|
||||
var pos: RelPos,
|
||||
val padMap: Map<Char, RelPos>,
|
||||
val child: PadState? = null,
|
||||
val cache: MutableMap<Pair<RelPos, RelPos>, Long> = HashMap()
|
||||
) {
|
||||
fun getMovement(c: Char): Long {
|
||||
val targetPos = padMap[c]!!
|
||||
return if (child == null) {
|
||||
1
|
||||
} else {
|
||||
val movement = cache.getOrPut(pos to targetPos) {
|
||||
val child = child
|
||||
var sum = 0L
|
||||
if (pos.dr == 0 && targetPos.dc == -2) {
|
||||
while (targetPos.dr < pos.dr) {
|
||||
sum += child.getMovement('^')
|
||||
pos = pos.translate(0, -1)
|
||||
}
|
||||
while (targetPos.dr > pos.dr) {
|
||||
sum += child.getMovement('v')
|
||||
pos = pos.translate(0, 1)
|
||||
}
|
||||
}
|
||||
if (pos.dc == -2 && targetPos.dr == 0) {
|
||||
while (targetPos.dc > pos.dc) {
|
||||
sum += child.getMovement('>')
|
||||
pos = pos.translate(1, 0)
|
||||
}
|
||||
}
|
||||
while (targetPos.dc < pos.dc) {
|
||||
sum += child.getMovement('<')
|
||||
pos = pos.translate(-1, 0)
|
||||
}
|
||||
while (targetPos.dr > pos.dr) {
|
||||
sum += child.getMovement('v')
|
||||
pos = pos.translate(0, 1)
|
||||
}
|
||||
while (targetPos.dr < pos.dr) {
|
||||
sum += child.getMovement('^')
|
||||
pos = pos.translate(0, -1)
|
||||
}
|
||||
while (targetPos.dc > pos.dc) {
|
||||
sum += child.getMovement('>')
|
||||
pos = pos.translate(1, 0)
|
||||
}
|
||||
|
||||
sum += child.getMovement('A')
|
||||
sum
|
||||
}
|
||||
|
||||
pos = targetPos
|
||||
movement
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun part1(input: List<String>): Long {
|
||||
val home = RelPos(0, 0)
|
||||
val myPad = PadState(home, robotPadMap)
|
||||
val robotPad2 = PadState(home, robotPadMap, myPad)
|
||||
val robotPad1 = PadState(home, robotPadMap, robotPad2)
|
||||
val doorPad = PadState(home, doorPadMap, robotPad1)
|
||||
var sum = 0L
|
||||
for (seq in input) {
|
||||
val seqVal = seq.take(3).toLong()
|
||||
sum += seq.sumOf { doorPad.getMovement(it) } * seqVal
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun part2(input: List<String>): Long {
|
||||
val home = RelPos(0, 0)
|
||||
val myPad = PadState(home, robotPadMap)
|
||||
var lastPad = myPad
|
||||
Array(25) { PadState(home, robotPadMap, lastPad).also { lastPad = it } }
|
||||
val doorPad = PadState(home, doorPadMap, lastPad)
|
||||
var sum = 0L
|
||||
for (seq in input) {
|
||||
val seqVal = seq.take(3).toLong()
|
||||
sum += seq.sumOf { doorPad.getMovement(it) } * seqVal
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// test if implementation meets criteria from the description, like:
|
||||
val testInput = inlineTestInput.trim().reader().readLines()
|
||||
//val testInput = readInput("aoc2024/Day21_test")
|
||||
val testInputPart1Result = part1(testInput)
|
||||
println("Part 1 Test: $testInputPart1Result")
|
||||
val testInputPart2Result = part2(testInput)
|
||||
println("Part 2 Test: $testInputPart2Result")
|
||||
check(testInputPart1Result == 126384L)
|
||||
//check(testInputPart2Result == 0)
|
||||
|
||||
val input = readInput("aoc2024/Day21")
|
||||
part1(input).println()
|
||||
part2(input).println()
|
||||
}
|
Loading…
Reference in New Issue
Block a user