-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay18.kt
74 lines (63 loc) · 2.48 KB
/
Day18.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
private fun getTrenchSize(instructions: List<Pair<Direction, Int>>): Long {
val verticalIntervals = buildList {
instructions.fold(Index2(0, 0)) { currentIndex, (dir, dist) ->
val next = currentIndex + dir.index2 * dist
when (dir) {
Direction.Up -> add(currentIndex.j to next.i..currentIndex.i)
Direction.Down -> add(currentIndex.j to currentIndex.i..next.i)
else -> {}
}
next
}
}
return verticalIntervals.asSequence()
.flatMap { (_, range) -> sequenceOf(range.first, range.last) }
.sorted()
.distinct()
.zipWithNext()
.fold(0L to listOf<Interval>()) { (sum, previousHorizontalIntervals), (a, b) ->
val currentHorizontalIntervals = verticalIntervals.asSequence()
.filter { a in it.second && b in it.second }
.map { it.first }
.sorted()
.chunked(2) { (c, d) -> Interval(c, d) }
.toList()
val intervalLength = currentHorizontalIntervals.sumOf { it.end - it.start + 1 }
val overlappingLength = currentHorizontalIntervals.sumOf { interval ->
previousHorizontalIntervals.sumOf { (it intersect interval).size }
}
sum + intervalLength * (b - a + 1) - overlappingLength to currentHorizontalIntervals
}
.first
}
fun main() {
data class Input(val direction: Direction, val distance: Int, val color: String)
val instructions = mapLines { line ->
val (directionString, distanceString, colorString) = line.split(' ')
Input(
when (directionString) {
"R" -> Direction.Right
"L" -> Direction.Left
"U" -> Direction.Up
"D" -> Direction.Down
else -> expect()
},
distanceString.toInt(),
colorString.substring(2, 8),
)
}
val first = getTrenchSize(instructions.map { it.direction to it.distance })
val decodedInstructions = instructions.map {
val direction = when (it.color.last()) {
'0' -> Direction.Right
'1' -> Direction.Down
'2' -> Direction.Left
'3' -> Direction.Up
else -> expect()
}
val distance = it.color.substring(0, 5).toInt(16)
direction to distance
}
val second = getTrenchSize(decodedInstructions)
println("$first $second")
}