-
Notifications
You must be signed in to change notification settings - Fork 0
/
day10.kt
63 lines (52 loc) · 1.92 KB
/
day10.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
package day10
import assertEquals
import benchmark
import readInputLines
fun main() {
val day = "10"
val demoInputLines = readInputLines("day$day-demo")
assertEquals(solvePart1(demoInputLines), 13140)
val inputLines = readInputLines("day$day")
benchmark { solvePart1(inputLines).also { println("Solution part one: $it") } }
benchmark { solvePart2(inputLines) }
}
sealed interface Operation {
object Noop : Operation
class MoveSpriteOp(val offset: Int) : Operation
}
private fun solvePart1(input: List<String>): Int {
val ticks = input.map { parseOperation(line = it.trim()) }
.scan(Pair(emptyList<Int>(), 1)) { prevOpRes, op ->
processOperation(op = op, spritePos = prevOpRes.second)
}.flatMap { it.first }
val relevantCyclesNum = (ticks.size - 20).floorDiv(40) + 1
return (0 until relevantCyclesNum)
.map { 20 + (it.times(40)) }
.sumOf { index -> index * ticks[index - 1] }
}
private fun solvePart2(input: List<String>) {
input.map { parseOperation(line = it.trim()) }
.scan(Pair(emptyList<Int>(), 1)) { prevOpRes, op ->
processOperation(op = op, spritePos = prevOpRes.second)
}.flatMap { it.first }
.mapIndexed { index, spritePos ->
if (listOf(spritePos - 1, spritePos, spritePos + 1).contains(index % 40)) "#" else ' '
}.chunked(40).forEach {
println(it.joinToString(" "))
}
}
private fun processOperation(op: Operation, spritePos: Int): Pair<List<Int>, Int> {
return when (op) {
is Operation.MoveSpriteOp -> {
val ticks = listOf(spritePos, spritePos)
return Pair(ticks, spritePos + op.offset)
}
else -> Pair(listOf(spritePos), spritePos)
}
}
private fun parseOperation(line: String): Operation {
return when (line) {
"noop" -> Operation.Noop
else -> Operation.MoveSpriteOp(line.split(" ")[1].toInt())
}
}