-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path23.kt
81 lines (67 loc) · 2.51 KB
/
23.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
private operator fun Pair<Int, Int>.plus(o: Pair<Int, Int>) = Pair(this.first + o.first, this.second + o.second)
fun main() {
val terrain = generateSequence { readlnOrNull() }.toList()
val elves = mutableListOf<Pair<Int, Int>>()
for (y in terrain.indices) for (x in terrain[0].indices) if (terrain[y][x] == '#') elves.add(Pair(x, y))
val dirs = listOf(
listOf(Pair(1, -1), Pair(0, -1), Pair(-1, -1)),
listOf(Pair(1, 1), Pair(0, 1), Pair(-1, 1)),
listOf(Pair(-1, -1), Pair(-1, 0), Pair(-1, 1)),
listOf(Pair(1, -1), Pair(1, 0), Pair(1, 1)),
)
var out1 = 0
val out2: Int
var round = 0
while (true) {
round += 1
val nextPositions = mutableMapOf<Pair<Int, Int>, MutableList<Int>>().withDefault { mutableListOf() }
for ((elfIndex, elf) in elves.withIndex()) {
val foundAnyElf = dirs.any { it.any { offset -> (elf + offset) in elves } }
if (foundAnyElf) {
var nextPos = elf
for (i in 0 until 4) {
val offsets = dirs[(round - 1 + i) % 4]
val foundElf = offsets.any { (elf + it) in elves }
if (!foundElf) {
nextPos = elf + offsets[1]
break
}
}
if (nextPos !in nextPositions) nextPositions[nextPos] = mutableListOf()
nextPositions[nextPos]!!.add(elfIndex)
}
}
if (nextPositions.isEmpty()) {
out2 = round
break
}
for (pos in nextPositions.keys) {
val elfIndices = nextPositions[pos]!!
if (elfIndices.size == 1) {
elves[elfIndices[0]] = pos
}
}
if (round == 10) {
val xs = elves.map { it.first }
val ys = elves.map { it.second }
val xl = xs.maxOf { it } - xs.minOf { it } + 1
val yl = ys.maxOf { it } - ys.minOf { it } + 1
out1 = xl * yl - elves.size
}
}
// visualize end
val xs = elves.map { it.first }
val ys = elves.map { it.second }
for (y in (ys.minOf { it }..ys.maxOf { it })) {
for (x in (xs.minOf { it }..xs.maxOf { it })) {
if (Pair(x, y) !in elves) print('.')
else print('#')
}
println()
}
println()
println(out1)
println(out2)
assert(out1 == 4052) { "First answer $out1 is wrong." }
assert(out2 == 978) { "Second answer $out2 is wrong." }
}