-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay03.kt
67 lines (58 loc) · 2.25 KB
/
Day03.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
package io.dmitrijs.aoc2023
@Suppress("NestedBlockDepth")
class Day03(private val input: List<String>) {
private val maxX = input.first().lastIndex
private val maxY = input.lastIndex
fun puzzle1(): Long {
val result = mutableListOf<Long>()
var number = ""
var append = false
input.indices.forEach { y ->
input[y].indices.forEach { x ->
val p = Point(x, y)
if (p.isDigit) {
number += p.value
if (!append && p.validNeighbours().any { it.isChar }) append = true
}
if ((!p.isDigit || p.x == maxX) && number.isNotEmpty()) {
if (append) result.add(number.toLong())
number = ""
append = false
}
}
}
return result.sum()
}
fun puzzle2(): Long {
val result = hashMapOf<Point, MutableList<Long>>()
var number = ""
val currentGears = hashSetOf<Point>()
input.indices.forEach { y ->
input[y].indices.forEach { x ->
val p = Point(x, y)
if (p.isDigit) {
number += p.value
currentGears.addAll(p.validNeighbours().filter { it.isGear })
}
if ((!p.isDigit || p.x == maxX) && number.isNotEmpty()) {
currentGears.forEach { gear ->
if (gear in result) {
result.getValue(gear).add(number.toLong())
} else {
result[gear] = mutableListOf(number.toLong())
}
}
currentGears.clear()
number = ""
}
}
}
return result.filterValues { it.size == 2 }.values.sumOf { it[0] * it[1] }
}
private val Point.value get() = input[y][x]
private val Point.isChar get() = !isSpace && !isDigit
private val Point.isGear get() = value == '*'
private val Point.isSpace get() = value == '.'
private val Point.isDigit get() = value.isDigit()
private fun Point.validNeighbours() = neighbours().filter { it.x in 0..maxX && it.y in 0..maxY }
}