@@ -64,6 +64,58 @@ object Day15 : DayOf2024(15) {
6464
6565 return (finalBoxes - finalRobot).sumOf { it.y * 100 + it.x }
6666 }
67+ 68+ override fun second (): Any? {
69+ val (rawMap, rawOps) = data.split(" \n\n " )
70+ val ops = rawOps.filter { it in dirs }
71+ 72+ val startMap = rawMap.lines().map { it.toList() }
73+ val startRobot = startMap.find(' @' )!! .let { Vector2D (it.x * 2 , it.y) }
74+ val startBoxes = buildSet {
75+ startMap.forEachIndexed { y, row ->
76+ row.forEachIndexed { x, c ->
77+ if (c == ' O' ) {
78+ add(Vector2D (2 * x, y) to Vector2D (2 * x + 1 , y))
79+ }
80+ }
81+ }
82+ }
83+ 84+ val walls = buildSet {
85+ startMap.forEachIndexed { y, row ->
86+ row.forEachIndexed { x, c ->
87+ if (c == ' #' ) {
88+ add(Vector2D (2 * x, y))
89+ add(Vector2D (2 * x + 1 , y))
90+ }
91+ }
92+ }
93+ }
94+ 95+ val (_, finalBoxes) = ops.fold(startRobot to startBoxes) { (robot, boxes), op ->
96+ val dir = dirs.getValue(op)
97+ 98+ val movingBlocks = generateSequence(setOf (robot)) { curr ->
99+ val next = curr.map { it + dir.step }
100+ val front = boxes.filter { it.first in next || it.second in next }
101+ 102+ curr + front.flatMap { it.toList() }
103+ }
104+ .zipWithNext()
105+ .first { it.first == it.second }
106+ .first
107+ 108+ if (movingBlocks.any { it + dir.step in walls }) {
109+ robot to boxes
110+ } else {
111+ val (boxesToMove, boxesToStay) = boxes.partition { it.first in movingBlocks }
112+ 113+ (robot + dir.step) to (boxesToStay + boxesToMove.map { it.first + dir.step to it.second + dir.step }).toSet()
114+ }
115+ }
116+ 117+ return finalBoxes.sumOf { it.first.y * 100 + it.first.x }
118+ }
67119}
68120
69121fun main () = SomeDay .mainify(Day15 )
0 commit comments