-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day05.kt
92 lines (75 loc) · 2.78 KB
/
Day05.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package day05
import common.InputRepo
import common.readSessionCookie
import common.solve
import util.split
fun main(args: Array<String>) {
val day = 5
val input = InputRepo(args.readSessionCookie()).get(day = day)
solve(day, input, ::solveDay05Part1, ::solveDay05Part2)
}
fun solveDay05Part1(input: List<String>): String {
val (initialConditions, instructions) = input.split({ it.isBlank() })
val map = generateStackMap(initialConditions)
for (instructionLine in instructions) {
val instruction = parseInstruction(instructionLine)
repeat(instruction.repetitions) {
val removed = map[instruction.origin]!!.removeLast()
map[instruction.target]?.addLast(removed)
}
}
return map.values.mapNotNull { it.lastOrNull() }
.joinToString(separator = "") { it.toString() }
}
private fun generateStackMap(split: Collection<String>): MutableMap<Int, ArrayDeque<Char>> {
val initialStrings = split.reversed()
var numOfStacks: Int
val map = mutableMapOf<Int, ArrayDeque<Char>>()
for ((index, initialString) in initialStrings.withIndex()) {
if (index == 0) {
numOfStacks = initialString.split("""\w""".toRegex()).count()
for (i in 0..numOfStacks) {
map[i] = ArrayDeque()
}
} else {
initialString
.windowed(3, 4)
.mapIndexed { i, s ->
if (s.isNotBlank()) {
map[i]?.addLast(getChar(s))
}
}
}
}
return map
}
private fun getChar(boxSyntax: String): Char {
return boxSyntax.toCharArray()[1]
}
data class Instruction(val repetitions: Int, val origin: Int, val target: Int)
private fun parseInstruction(line: String): Instruction {
val moveRegex = """move (\d+) from (\d+) to (\d+)""".toRegex()
return moveRegex.matchEntire(line)
?.destructured
?.let { (repetitions, origin, target) ->
Instruction(repetitions.toInt(), origin.toInt() - 1, target.toInt() - 1)
}
?: throw IllegalArgumentException("Bad input '$line'")
}
fun solveDay05Part2(input: List<String>): String {
val (initialConditions, instructions) = input.split({ it.isBlank() })
val map = generateStackMap(initialConditions)
for (instructionLine in instructions) {
val instruction = parseInstruction(instructionLine)
val removedList = mutableListOf<Char>()
repeat(instruction.repetitions) {
removedList.add(map[instruction.origin]!!.removeLast())
}
removedList.reversed().forEach {
map[instruction.target]?.add(it)
}
}
return map.values
.mapNotNull { it.lastOrNull() }
.joinToString(separator = "") { it.toString() }
}