-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day14.kt
72 lines (60 loc) · 2.41 KB
/
Day14.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
package aoc2023.day14
import aoc2021.day25.printMap
import util.Coord
fun part1(map: Map<Coord, Char>): Int {
return computeTotalLoad(tiltMap(map, ::getNorthCoord), getTotRows(map))
}
fun part2(map: Map<Coord, Char>, period: Int): Int {
val periodStarts = 90 // Valid for both test and real input
val remainder = (1000000000 - periodStarts) % period
var cycledMap = map.toMutableMap()
repeat(periodStarts + remainder) {
cycledMap = runTiltCycle(cycledMap)
}
return computeTotalLoad(cycledMap, getTotRows(map))
}
private fun computeTotalLoad(tiltedMap: MutableMap<Coord, Char>, totRows: Int): Int {
return tiltedMap
.entries
.filter { it.value == 'O' }
.sumOf { totRows - it.key.y }
}
private fun tiltMap(map: Map<Coord, Char>, getDirCoord: (Coord) -> Coord): MutableMap<Coord, Char> {
val tiltedMap = map.toMutableMap()
var inputMap = map.toMutableMap()
if (getDirCoord == ::getSouthCoord || getDirCoord == ::getEastCoord) {
inputMap = reverseMap(inputMap).toMutableMap()
}
for (entry in inputMap.entries) {
if (entry.value == 'O') {
var direction = entry.key
while (tiltedMap[getDirCoord(direction)] != null && tiltedMap[getDirCoord(direction)] == '.') {
direction = getDirCoord(direction)
}
if (entry.key != direction) {
tiltedMap[entry.key] = '.'
tiltedMap[direction] = 'O'
}
}
}
return tiltedMap
}
private fun runTiltCycle(inputMap: Map<Coord, Char>): MutableMap<Coord, Char> {
var tiltedMap = inputMap.toMutableMap()
val tiltFunctions = listOf(::getNorthCoord, ::getWestCoord, ::getSouthCoord, ::getEastCoord)
for (tiltFunction in tiltFunctions) {
tiltedMap = tiltMap(tiltedMap.toMutableMap(), tiltFunction)
}
return tiltedMap
}
private fun getNorthCoord(coord: Coord) = Coord(coord.x, coord.y - 1)
private fun getSouthCoord(coord: Coord) = Coord(coord.x, coord.y + 1)
private fun getWestCoord(coord: Coord) = Coord(coord.x - 1, coord.y)
private fun getEastCoord(coord: Coord) = Coord(coord.x + 1, coord.y)
private fun getTotRows(map: Map<Coord, Char>) = map.keys.maxBy { it.y }.y + 1
private fun reverseMap(inputMap: Map<Coord, Char>): Map<Coord, Char> {
return inputMap.entries
.sortedByDescending { it.key.x }
.sortedByDescending { it.key.y }
.associate { it.toPair() }
}