generated from Jadarma/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathY2015D06.kt
76 lines (64 loc) · 2.62 KB
/
Y2015D06.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
package aockt.y2015
import aockt.y2015.Y2015D06.Action.*
import io.github.jadarma.aockt.core.Solution
import kotlin.math.abs
object Y2015D06 : Solution {
private enum class Action { TURN_ON, TOGGLE, TURN_OFF }
private data class Rectangle(val x1: Int, val y1: Int, val x2: Int, val y2: Int)
/** Regex that can parse the syntax of Santa's instructions. */
private val instructionRegex = Regex("""(toggle|turn off|turn on) (\d+),(\d+) through (\d+),(\d+)""")
private fun String.parseInstruction(): Pair<Action, Rectangle> = runCatching {
val (rawAction, x1, y1, x2, y2) = instructionRegex.matchEntire(this)!!.destructured
val action = Action.valueOf(rawAction.replace(' ', '_').uppercase())
val rectangle = Rectangle(x1.toInt(), y1.toInt(), x2.toInt(), y2.toInt())
action to rectangle
}.getOrElse { throw IllegalArgumentException("Invalid instruction: $this") }
private class LightGrid(size: Int) {
private val grid = Array(size) { Array(size) { 0 } }
/**
* Returns the total sum of values for all cells in the grid.
* This is somewhat prone to overflowing. It is safe up until a value of 2000 brightness per cell.
*/
fun sum() = grid.sumOf { it.sum() }
/** For all points that overlap the [rectangle], update the cell value by applying the [mapper] function. */
fun mapRectangle(rectangle: Rectangle, mapper: (Int) -> Int) {
with(rectangle) {
for (x in x1..x2) {
for (y in y1..y2) {
grid[x][y] = mapper(grid[x][y])
}
}
}
}
}
override fun partOne(input: String) = with(LightGrid(1000)) {
input
.lineSequence()
.map { it.parseInstruction() }
.forEach { (action, rectangle) ->
mapRectangle(rectangle) { value ->
when (action) {
TURN_ON -> 1
TOGGLE -> abs(value - 1)
TURN_OFF -> 0
}
}
}
sum()
}
override fun partTwo(input: String) = with(LightGrid(1000)) {
input
.lineSequence()
.map { it.parseInstruction() }
.forEach { (action, rectangle) ->
mapRectangle(rectangle) { value ->
when (action) {
TURN_ON -> value + 1
TOGGLE -> value + 2
TURN_OFF -> maxOf(value - 1, 0)
}
}
}
sum()
}
}