|
| 1 | +// AOC Day 5 |
| 2 | + |
| 3 | +typealias Container = Char |
| 4 | +typealias ContainerStack = ArrayDeque<Container> |
| 5 | +typealias StackNumber = Int |
| 6 | + |
| 7 | +data class MoveInstruction(val amount: Int, val from: Int, val to: Int) |
| 8 | + |
| 9 | +fun Map<StackNumber, ContainerStack>.deepCopy(): Map<StackNumber, ContainerStack> { |
| 10 | + return toMap().mapValues { ArrayDeque(it.value) } |
| 11 | +} |
| 12 | + |
| 13 | + |
| 14 | +fun part1(stacks: Map<StackNumber, ContainerStack>, instructions: Collection<MoveInstruction>) { |
| 15 | + instructions.forEach { (amount, from, to) -> |
| 16 | + repeat(amount) { |
| 17 | + stacks[from]!!.removeFirst().also { stacks[to]!!.addFirst(it) } |
| 18 | + } |
| 19 | + } |
| 20 | + |
| 21 | + val topContainersText = stacks.toSortedMap().values.map { it.first() }.joinToString("") |
| 22 | + |
| 23 | + println("Part 1: The top most containers form the text $topContainersText") |
| 24 | +} |
| 25 | + |
| 26 | +fun part2(stacks: Map<StackNumber, ContainerStack>, instructions: Collection<MoveInstruction>) { |
| 27 | + instructions.forEach { (amount, from, to) -> |
| 28 | + val transferStack = ContainerStack() |
| 29 | + repeat(amount) { |
| 30 | + stacks[from]!!.removeFirst().also { transferStack.addFirst(it) } |
| 31 | + } |
| 32 | + repeat(amount) { |
| 33 | + transferStack.removeFirst().also { stacks[to]!!.addFirst(it) } |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + val topContainersText = stacks.toSortedMap().values.map { it.first() }.joinToString("") |
| 38 | + |
| 39 | + println("Part 2: The top most containers form the text $topContainersText") |
| 40 | +} |
| 41 | + |
| 42 | +val INSTRUCTION_REGEX = Regex("\\d+") |
| 43 | +fun main() { |
| 44 | + val (stacks, instructions) = getAOCInput { rawInput -> |
| 45 | + val (sectionStacks, sectionInstructions) = rawInput.trim('\n').splitInTwo("\n\n").run { |
| 46 | + first.split("\n") to second.split("\n") |
| 47 | + } |
| 48 | + |
| 49 | + val stacks = mutableMapOf<StackNumber, ContainerStack>() |
| 50 | + sectionStacks.last().forEachIndexed { charIndex, char -> |
| 51 | + if (char.isDigit()) { |
| 52 | + val stack = ContainerStack().also { stacks[char.digitToInt()] = it } |
| 53 | + for (layer in sectionStacks.dropLast(1).reversed()) { |
| 54 | + val containerLabel = layer[charIndex] |
| 55 | + if (containerLabel.isLetter()) stack.addFirst(layer[charIndex]) |
| 56 | + } |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + val instructions = sectionInstructions.map { rawInstruction -> |
| 61 | + val instructionValues = INSTRUCTION_REGEX.findAll(rawInstruction).toList().map { it.value }.mapToInt() |
| 62 | + MoveInstruction(instructionValues[0], instructionValues[1], instructionValues[2]) |
| 63 | + } |
| 64 | + |
| 65 | + stacks to instructions |
| 66 | + } |
| 67 | + |
| 68 | + part1(stacks.deepCopy(), instructions) |
| 69 | + part2(stacks.deepCopy(), instructions) |
| 70 | +} |
0 commit comments