From 63b00c3a154732a9973f19497f2ee8f8dd6c105c Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Mon, 16 Dec 2024 21:20:34 +0100 Subject: [PATCH] WIP Day 15 Part 2 --- 2024/src/main/kotlin/Direction.kt | 10 +-- 2024/src/main/kotlin/day15.kt | 93 +++++++++++++++++++++++- 2024/src/main/resources/day15-sample.txt | 21 ++++++ 3 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 2024/src/main/resources/day15-sample.txt diff --git a/2024/src/main/kotlin/Direction.kt b/2024/src/main/kotlin/Direction.kt index bc30103..23425d6 100644 --- a/2024/src/main/kotlin/Direction.kt +++ b/2024/src/main/kotlin/Direction.kt @@ -12,10 +12,10 @@ enum class Direction { } } -fun Grid.Coordinate.step(direction: Direction) = +fun Grid.Coordinate.step(direction: Direction, steps: Int = 1) = when (direction) { - Direction.North -> copy(y = y - 1) - Direction.East -> copy(x = x + 1) - Direction.South -> copy(y = y + 1) - Direction.West -> copy(x = x - 1) + Direction.North -> copy(y = y - steps) + Direction.East -> copy(x = x + steps) + Direction.South -> copy(y = y + steps) + Direction.West -> copy(x = x - steps) } \ No newline at end of file diff --git a/2024/src/main/kotlin/day15.kt b/2024/src/main/kotlin/day15.kt index 966a790..1885766 100644 --- a/2024/src/main/kotlin/day15.kt +++ b/2024/src/main/kotlin/day15.kt @@ -1,9 +1,19 @@ fun main() { - val iterator = readInput("day15.txt").iterator() + val iterator = readInput("day15-sample.txt").iterator() val input = Sequence { iterator } val grid = CharGrid(input.takeWhile { it.isNotEmpty() }.toList()) - var robot = grid.find('@')!! + + val grid2 = CharGrid(grid.rows.map { + it.map { + when (it) { + '@' -> "@." + 'O' -> "[]" + else -> "$it$it" + } + }.joinToString(separator = "") + }) + val program = input.flatMap { line -> line.map { @@ -15,8 +25,9 @@ fun main() { else -> error("Invalid direction $it") } } - } + }.toList() + var robot = grid.find('@')!! grid[robot] = '.' for (direction in program) { val next = robot.step(direction) @@ -32,6 +43,25 @@ fun main() { } println("Part 1: $part1") + + robot = grid2.find('@')!! + grid2[robot] = '.' + for (direction in program) { + val next = robot.step(direction) + if (grid2.pushWide(next, direction)) { + robot = next + } + } + + val part2 = grid2.coordinates() + .filter { grid2[it] == '[' } + .fold(0) { acc, coord -> + acc + coord.x + 100 * coord.y + } + + println(grid2.rows.joinToString(separator = "\n")) + + println("Part 2: $part2") } fun CharGrid.push(position: Grid.Coordinate, direction: Direction): Boolean { @@ -53,3 +83,60 @@ fun CharGrid.push(position: Grid.Coordinate, direction: Direction): Boolean { return true } + +fun CharGrid.pushWide(position: Grid.Coordinate, direction: Direction): Boolean { + if (!canPushWide(position, direction)) return false + + doPushWide(position, direction) + + return true +} + +fun CharGrid.doPushWide(position: Grid.Coordinate, direction: Direction, fill: Char = '.') { + if (this[position] != '[' && this[position] != ']') return + + when (direction) { + Direction.East, Direction.West -> { + val next = position.step(direction) + doPushWide(next, direction, this[position]) + this[position] = fill + } + + Direction.South, Direction.North -> { + val boxStart = if (this[position] == '[') position else position.step(Direction.West) + val boxEnd = boxStart.step(Direction.East) + + val nextStart = boxStart.step(direction) + val nextEnd = boxStart.step(direction) + + doPushWide(nextStart, direction, this[boxStart]) + doPushWide(nextEnd, direction, this[boxEnd]) + + this[boxStart] = fill + this[boxEnd] = fill + } + } +} + +fun CharGrid.canPushWide(position: Grid.Coordinate, direction: Direction): Boolean { + val boxStart = when (this[position]) { + '.' -> return true + '[' -> position + ']' -> { + val start = position.copy(x = position.x - 1) + require(this[start] == '[') + start + } + + else -> return false + } + + val boxEnd = boxStart.step(Direction.East) + + return when (direction) { + Direction.East -> canPushWide(boxEnd.step(Direction.East), direction) + Direction.West -> canPushWide(boxStart.step(Direction.West), direction) + Direction.North, Direction.South -> canPushWide(boxStart.step(direction), direction) && + canPushWide(boxEnd.step(direction), direction) + } +} \ No newline at end of file diff --git a/2024/src/main/resources/day15-sample.txt b/2024/src/main/resources/day15-sample.txt new file mode 100644 index 0000000..b2bce78 --- /dev/null +++ b/2024/src/main/resources/day15-sample.txt @@ -0,0 +1,21 @@ +########## +#..O..O.O# +#......O.# +#.OO..O.O# +#..O@..O.# +#O#..O...# +#O..O..O.# +#.OO.O.OO# +#....O...# +########## + +^v>^vv^v>v<>v^v<<><>>v^v^>^<<<><^ +vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<^<^^>>>^<>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^v^^<^^vv< +<>^^^^>>>v^<>vvv^>^^^vv^^>v<^^^^v<>^>vvvv><>>v^<<^^^^^ +^><^><>>><>^^<<^^v>>><^^>v>>>^v><>^v><<<>vvvv>^<><<>^>< +^>><>^v<><^vvv<^^<><^v<<<><<<^^<^>>^<<<^>>^v^>>^v>vv>^<<^v<>><<><<>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^ +<><^^>^^^<>^vv<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<> +^^>vv<^v^v^<>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<>< +v^^>>><<^^<>>^v^v^<<>^<^v^v><^<<<><<^vv>>v>v^<<^ \ No newline at end of file