-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay16.kt
114 lines (94 loc) · 3.4 KB
/
Day16.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package adventofcode2023
import java.io.File
object Day16 {
private const val UPWARDS = '^'
private const val DOWNWARDS = 'v'
private const val LEFTWARDS = '<'
private const val RIGHTWARDS = '>'
private val beamVectors = mapOf(
UPWARDS to Pair(0, -1),
DOWNWARDS to Pair(0, 1),
LEFTWARDS to Pair(-1, 0),
RIGHTWARDS to Pair(1, 0)
)
private val beamModifiers = mapOf(
'\\' to mapOf(
RIGHTWARDS to setOf(DOWNWARDS),
LEFTWARDS to setOf(UPWARDS),
UPWARDS to setOf(LEFTWARDS),
DOWNWARDS to setOf(RIGHTWARDS)
),
'/' to mapOf(
RIGHTWARDS to setOf(UPWARDS),
LEFTWARDS to setOf(DOWNWARDS),
UPWARDS to setOf(RIGHTWARDS),
DOWNWARDS to setOf(LEFTWARDS)
),
'-' to mapOf(
RIGHTWARDS to setOf(RIGHTWARDS),
LEFTWARDS to setOf(LEFTWARDS),
UPWARDS to setOf(LEFTWARDS, RIGHTWARDS),
DOWNWARDS to setOf(LEFTWARDS, RIGHTWARDS)
),
'|' to mapOf(
RIGHTWARDS to setOf(UPWARDS, DOWNWARDS),
LEFTWARDS to setOf(UPWARDS, DOWNWARDS),
UPWARDS to setOf(UPWARDS),
DOWNWARDS to setOf(DOWNWARDS)
)
)
private val inputs = File("resources/adventofcode2023/Day16.txt").readLines()
private fun isLocationInBounds(x: Int, y: Int): Boolean =
(x >= 0 && y >= 0 && x < inputs[0].length && y < inputs.size)
private fun getBeamLocations(
startingX: Int,
startingY: Int,
startingDirection: Char
): List<List<List<Char>>> {
val beamLocations = List(inputs.size) { List(inputs[0].length) { mutableListOf<Char>() } }
fun sendBeam(initX: Int, initY: Int, direction: Char) {
var x = initX
var y = initY
val shiftVector = beamVectors[direction]!!
while (isLocationInBounds(x, y)) {
if (beamLocations[y][x].contains(direction)) return
beamLocations[y][x].add(direction)
if (beamModifiers.keys.contains(inputs[y][x])) {
beamModifiers[inputs[y][x]]?.get(direction)?.forEach {
sendBeam(x + beamVectors[it]!!.first, y + beamVectors[it]!!.second, it)
}
return
}
x += shiftVector.first
y += shiftVector.second
}
}
sendBeam(startingX, startingY, startingDirection)
return beamLocations
}
private fun countEnergizedTiles(beamLocations: List<List<List<Char>>>): Int =
beamLocations.sumOf { line -> line.count { it.isNotEmpty() } }
fun part1() = println(countEnergizedTiles(getBeamLocations(0, 0, RIGHTWARDS)))
fun part2() {
var max = 0
for (y in inputs.indices) {
max = maxOf(
max,
countEnergizedTiles(getBeamLocations(0, y, RIGHTWARDS)),
countEnergizedTiles(getBeamLocations(inputs[y].length - 1, y, LEFTWARDS))
)
}
for (x in inputs[0].indices) {
max = maxOf(
max,
countEnergizedTiles(getBeamLocations(x, 0, DOWNWARDS)),
countEnergizedTiles(getBeamLocations(x, inputs.size - 1, UPWARDS))
)
}
println(max)
}
}
fun main() {
Day16.part1()
Day16.part2()
}