-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day24.kt
121 lines (109 loc) · 4.42 KB
/
Day24.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
115
116
117
118
119
120
121
package adventOfCode2020.day24
import adventOfCode2020.day20.Coord
import java.io.File
fun readInputToList(path: String): List<List<HexNeighbors>> {
val lineList = mutableListOf<String>()
File(path).inputStream().bufferedReader().forEachLine { lineList.add(it) }
val inputList = mutableListOf<List<HexNeighbors>>()
for (line in lineList) {
val hexNeighbors = mutableListOf<HexNeighbors>()
var i = 0
while (i < line.length) {
if (line[i] == 'e' || line[i] == 'w') {
hexNeighbors.add(HexNeighbors.valueOf(line[i].toString().toUpperCase()))
i++
} else {
hexNeighbors.add(HexNeighbors.valueOf(line.substring(i, i + 2).toUpperCase()))
i += 2
}
}
inputList.add(hexNeighbors)
}
return inputList
}
fun findTilesAndCountBlackOnes(input: List<List<HexNeighbors>>): Int {
return getTiles(input).values.count { it == TileColor.BLACK }
}
private fun getTiles(input: List<List<HexNeighbors>>): Map<Coord, TileColor> {
val tilesMap = mutableMapOf<Coord, TileColor>()
tilesMap[Coord(0, 0)] = TileColor.WHITE
val deltaMap = getDeltaMap()
for (instructionList in input) {
var currentTile = Coord(0, 0)
for (instruction in instructionList) {
val delta = deltaMap[instruction]
val nextTileCoord = Coord(currentTile.x + delta!!.x, currentTile.y + delta.y)
if (!tilesMap.containsKey(nextTileCoord)) {
tilesMap[nextTileCoord] = TileColor.WHITE
}
currentTile = nextTileCoord
}
if (tilesMap.containsKey(currentTile)) {
tilesMap[currentTile] = if (tilesMap[currentTile] == TileColor.WHITE) TileColor.BLACK else TileColor.WHITE
} else {
tilesMap[currentTile] = TileColor.BLACK
}
}
return tilesMap
}
fun playGameOfTiles(input: List<List<HexNeighbors>>, days: Int): Int {
var tilesMap = extendTileMap(getTiles(input))
for (day in 1..days) {
val mapCopy = tilesMap.toMutableMap()
for (tile in tilesMap.entries) {
val blackNeighbors = getNeighborTiles(tile.key, tilesMap).count { it == TileColor.BLACK }
when (tile.value) {
TileColor.BLACK -> {
if (blackNeighbors == 0 || blackNeighbors > 2) {
mapCopy[tile.key] = TileColor.WHITE
} else mapCopy[tile.key] = TileColor.BLACK
}
TileColor.WHITE -> {
if (blackNeighbors == 2) {
mapCopy[tile.key] = TileColor.BLACK
} else mapCopy[tile.key] = TileColor.WHITE
}
}
}
tilesMap = extendTileMap(mapCopy)
}
return tilesMap.values.count { it == TileColor.BLACK }
}
private fun extendTileMap(tilesMap: Map<Coord, TileColor>): MutableMap<Coord, TileColor> {
val extendedMap = tilesMap.toMutableMap()
val minX = tilesMap.keys.mapTo(mutableSetOf()) { it.x }.minOrNull()!!
val maxX = tilesMap.keys.mapTo(mutableSetOf()) { it.x }.maxOrNull()!!
val minY = tilesMap.keys.mapTo(mutableSetOf()) { it.y }.minOrNull()!!
val maxY = tilesMap.keys.mapTo(mutableSetOf()) { it.y }.maxOrNull()!!
for (y in minY - 1..maxY + 1)
for (x in minX - 1..maxX + 1)
if (tilesMap[Coord(x, y)] == null) {
extendedMap[Coord(x, y)] = TileColor.WHITE
}
return extendedMap
}
private fun getDeltaMap(): MutableMap<HexNeighbors, Coord> {
val deltaMap = mutableMapOf<HexNeighbors, Coord>()
deltaMap[HexNeighbors.NW] = Coord(0, 1)
deltaMap[HexNeighbors.NE] = Coord(1, 1)
deltaMap[HexNeighbors.E] = Coord(1, 0)
deltaMap[HexNeighbors.SE] = Coord(0, -1)
deltaMap[HexNeighbors.SW] = Coord(-1, -1)
deltaMap[HexNeighbors.W] = Coord(-1, 0)
return deltaMap
}
private fun getNeighborTiles(tile: Coord, map: Map<Coord, TileColor>): List<TileColor> {
val deltaCoords = getDeltaMap().values
val neighbors = mutableListOf<TileColor>()
for (delta in deltaCoords) {
val neighborCoord = Coord(tile.x + delta.x, tile.y + delta.y)
var neighborTile = map[neighborCoord]
if (neighborTile == null) {
neighborTile = TileColor.WHITE
}
neighbors.add(neighborTile)
}
return neighbors
}
enum class HexNeighbors { E, NE, SE, W, NW, SW }
enum class TileColor { WHITE, BLACK }