|
| 1 | +data class Point(var x: Int, var y: Int, var z: Int) { |
| 2 | + operator fun plus(o: Point): Point = Point(x+o.x, y+o.y, z+o.z) |
| 3 | + fun adjacent(): List<Point> = dirs.map { this+it }.toList() |
| 4 | +} |
| 5 | + |
| 6 | +val dirs = listOf( |
| 7 | + Point(1, 0, 0), Point(0, 1, 0), Point(0, 0, 1), |
| 8 | + Point(-1, 0, 0), Point(0, -1, 0), Point(0, 0, -1), |
| 9 | +) |
| 10 | + |
| 11 | +fun main() { |
| 12 | + val input = generateSequence(::readlnOrNull) |
| 13 | + .map { it.split(",").map { it.toInt() } } |
| 14 | + .map { (x, y, z) -> Point(x, y, z) }.toList() |
| 15 | + val limitsX = input.minOf { it.x-1 }..input.maxOf { it.x+1 } |
| 16 | + val limitsY = input.minOf { it.y-1 }..input.maxOf { it.y+1 } |
| 17 | + val limitsZ = input.minOf { it.z-1 }..input.maxOf { it.z+1 } |
| 18 | + |
| 19 | + // Part 1 |
| 20 | + input.sumOf { it.adjacent().count { !input.contains(it) } }.run(::println) |
| 21 | + |
| 22 | + // Part 2 |
| 23 | + val queue = ArrayDeque<Point>() |
| 24 | + queue.add(Point(limitsX.first, limitsY.first, limitsZ.first)) |
| 25 | + var count = 0 |
| 26 | + val visited: MutableSet<Point> = mutableSetOf() |
| 27 | + while (queue.isNotEmpty()) { |
| 28 | + val point = queue.removeFirst() |
| 29 | + if (point in visited) continue |
| 30 | + visited.add(point) |
| 31 | + for (adj in point.adjacent()) { |
| 32 | + if (adj in input) |
| 33 | + count++ |
| 34 | + else if (adj.x in limitsX && adj.y in limitsY && adj.z in limitsZ) |
| 35 | + queue.add(adj) |
| 36 | + } |
| 37 | + } |
| 38 | + println(count) |
| 39 | +} |
0 commit comments