Day 15.
This commit is contained in:
parent
0592f4a862
commit
3ee70151f1
@ -51,7 +51,7 @@ p=9,5 v=-3,-3
|
||||
2) px == w/2, py > w/2 % h
|
||||
*/
|
||||
val z = Array(robots.size) { IntArray(4) }
|
||||
for (t in 1..1000000000L) {
|
||||
for (t in 1..w * h) {
|
||||
/*val good = robots.all {
|
||||
val x = ((it[0] + t * (it[2] + w)) % w).toInt()
|
||||
val y = ((it[1] + t * (it[3] + h)) % h).toInt()
|
||||
@ -68,7 +68,7 @@ p=9,5 v=-3,-3
|
||||
z.forEach { grid[it[0], it[1]] = '*' }
|
||||
grid.debug()
|
||||
println()
|
||||
break
|
||||
return t
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
230
src/aoc2024/Day15.kt
Normal file
230
src/aoc2024/Day15.kt
Normal file
@ -0,0 +1,230 @@
|
||||
package aoc2024
|
||||
|
||||
import CharGrid
|
||||
import println
|
||||
import readInput
|
||||
|
||||
/*
|
||||
--- Day 15: Warehouse Woes ---
|
||||
https://adventofcode.com/2024/day/15
|
||||
*/
|
||||
fun main() {
|
||||
|
||||
val inlineTestInput2 = """
|
||||
##########
|
||||
#..O..O.O#
|
||||
#......O.#
|
||||
#.OO..O.O#
|
||||
#..O@..O.#
|
||||
#O#..O...#
|
||||
#O..O..O.#
|
||||
#.OO.O.OO#
|
||||
#....O...#
|
||||
##########
|
||||
|
||||
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
|
||||
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
|
||||
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
|
||||
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
|
||||
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
|
||||
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
|
||||
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
|
||||
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
|
||||
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
|
||||
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^
|
||||
"""
|
||||
|
||||
val inlineTestInput = """
|
||||
########
|
||||
#..O.O.#
|
||||
##@.O..#
|
||||
#...O..#
|
||||
#.#.O..#
|
||||
#...O..#
|
||||
#......#
|
||||
########
|
||||
|
||||
<^^>>>vv<v>>v<<
|
||||
"""
|
||||
|
||||
val inlineTestInput3 = """
|
||||
#######
|
||||
#...#.#
|
||||
#.....#
|
||||
#..OO@#
|
||||
#..O..#
|
||||
#.....#
|
||||
#######
|
||||
|
||||
<vv<<^^<<^^
|
||||
"""
|
||||
|
||||
fun part1(input: List<String>): Int {
|
||||
val splitp = input.withIndex().find { it.value.isEmpty() }!!.index
|
||||
val grid = CharGrid(input.take(splitp))
|
||||
val inst = input.drop(splitp).joinToString("")
|
||||
var (rc, rd) = grid.findMatches { it == '@' }[0]
|
||||
for (m in inst) {
|
||||
grid[rc, rd] = '.'
|
||||
var dc = 0
|
||||
var dr = 0
|
||||
when (m) {
|
||||
'<' -> dc = -1
|
||||
'>' -> dc = 1
|
||||
'^' -> dr = -1
|
||||
'v' -> dr = 1
|
||||
}
|
||||
var s = 1
|
||||
while (grid[rc + dc * s, rd + dr * s] != '.') {
|
||||
if (grid[rc + dc * s, rd + dr * s] == '#') {
|
||||
s = 0
|
||||
break
|
||||
}
|
||||
s++
|
||||
}
|
||||
if (s > 0) {
|
||||
if (s > 1) {
|
||||
grid[rc + dc * s, rd + dr * s] = 'O'
|
||||
}
|
||||
rc += dc
|
||||
rd += dr
|
||||
}
|
||||
grid[rc, rd] = '@'
|
||||
}
|
||||
return grid.generateGridPos().filter { grid[it] == 'O' }.sumOf { it.dc + it.dr * 100 }
|
||||
}
|
||||
|
||||
fun canMove(grid: CharGrid, bc: Int, rd: Int, dr: Int): Boolean {
|
||||
if ((grid[bc, rd] == '[')) {
|
||||
val c1 = grid[bc, rd + dr]
|
||||
val c2 = grid[bc + 1, rd + dr]
|
||||
if ((c1 == '.') && (c2 == '.')) return true
|
||||
if ((c1 == '#') || (c2 == '#')) return false
|
||||
if ((c1 == '[')) return canMove(grid, bc, rd + dr, dr)
|
||||
return (if (c1 == ']') canMove(grid, bc - 1, rd + dr, dr) else true)
|
||||
&& (if (c2 == '[') canMove(grid, bc + 1, rd + dr, dr) else true)
|
||||
} else if ((grid[bc, rd] == ']')) {
|
||||
return canMove(grid, bc - 1, rd, dr)
|
||||
} else {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
fun doMove(grid: CharGrid, bc: Int, rd: Int, dr: Int) {
|
||||
if ((grid[bc, rd] == '[')) {
|
||||
val c1 = grid[bc, rd + dr]
|
||||
val c2 = grid[bc + 1, rd + dr]
|
||||
if ((c1 == '[')) {
|
||||
doMove(grid, bc, rd + dr, dr)
|
||||
} else {
|
||||
if (c1 == ']') doMove(grid, bc - 1, rd + dr, dr)
|
||||
if (c2 == '[') doMove(grid, bc + 1, rd + dr, dr)
|
||||
}
|
||||
if ((grid[bc, rd + dr] == '.') && (grid[bc + 1, rd + dr] == '.')) {
|
||||
grid[bc, rd + dr] = '['
|
||||
grid[bc + 1, rd + dr] = ']'
|
||||
grid[bc, rd] = '.'
|
||||
grid[bc + 1, rd] = '.'
|
||||
} else {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
} else if ((grid[bc, rd] == ']')) {
|
||||
doMove(grid, bc - 1, rd, dr)
|
||||
}
|
||||
}
|
||||
|
||||
fun part2(input: List<String>): Int {
|
||||
val splitp = input.withIndex().find { it.value.isEmpty() }!!.index
|
||||
val sgrid = CharGrid(input.take(splitp))
|
||||
val grid = CharGrid(sgrid.width * 2, sgrid.height)
|
||||
sgrid.generateGridPos().forEach {
|
||||
when (val cc = sgrid[it]) {
|
||||
'@' -> {
|
||||
grid[it.dc * 2, it.dr] = cc
|
||||
grid[it.dc * 2 + 1, it.dr] = '.'
|
||||
}
|
||||
|
||||
'O' -> {
|
||||
grid[it.dc * 2, it.dr] = '['
|
||||
grid[it.dc * 2 + 1, it.dr] = ']'
|
||||
}
|
||||
|
||||
else -> {
|
||||
grid[it.dc * 2, it.dr] = cc
|
||||
grid[it.dc * 2 + 1, it.dr] = cc
|
||||
}
|
||||
}
|
||||
}
|
||||
val inst = input.drop(splitp).joinToString("")
|
||||
var (rc, rd) = grid.findMatches { it == '@' }[0]
|
||||
for (m in inst) {
|
||||
grid[rc, rd] = '.'
|
||||
var dc = 0
|
||||
var dr = 0
|
||||
when (m) {
|
||||
'<' -> dc = -1
|
||||
'>' -> dc = 1
|
||||
'^' -> dr = -1
|
||||
'v' -> dr = 1
|
||||
}
|
||||
if (dc != 0) {
|
||||
var s = 1
|
||||
var bc: Char? = null
|
||||
while (grid[rc + dc * s, rd] != '.') {
|
||||
val cc = grid[rc + dc * s, rd]
|
||||
if (cc == '#') {
|
||||
s = 0
|
||||
break
|
||||
} else {
|
||||
if (bc != null && cc == bc) {
|
||||
s = 0
|
||||
break
|
||||
}
|
||||
bc = cc
|
||||
}
|
||||
s++
|
||||
}
|
||||
if (s > 0) {
|
||||
if (s > 1) {
|
||||
for (p in s downTo 1) {
|
||||
grid[rc + dc * p, rd] = grid[rc + dc * (p - 1), rd]
|
||||
}
|
||||
}
|
||||
rc += dc
|
||||
rd += dr
|
||||
}
|
||||
} else {
|
||||
if (grid[rc, rd + dr] != '.') {
|
||||
if (grid[rc, rd + dr] != '#') {
|
||||
if (canMove(grid, rc, rd + dr, dr)) {
|
||||
doMove(grid, rc, rd + dr, dr)
|
||||
rc += dc
|
||||
rd += dr
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rc += dc
|
||||
rd += dr
|
||||
}
|
||||
}
|
||||
grid[rc, rd] = '@'
|
||||
}
|
||||
return grid.generateGridPos().filter { grid[it] == '[' }.sumOf { it.dc + it.dr * 100 }
|
||||
}
|
||||
|
||||
// test if implementation meets criteria from the description, like:
|
||||
val testInput = inlineTestInput.trim().reader().readLines()
|
||||
val testInput2 = inlineTestInput2.trim().reader().readLines()
|
||||
val testInput3 = inlineTestInput3.trim().reader().readLines()
|
||||
//val testInput = readInput("aoc2024/Day15_test")
|
||||
val testInputPart1Result = part1(testInput)
|
||||
println("Part 1 Test: $testInputPart1Result")
|
||||
val testInputPart2Result = part2(testInput2)
|
||||
println("Part 2 Test: $testInputPart2Result")
|
||||
check(testInputPart1Result == 2028)
|
||||
check(testInputPart2Result == 9021)
|
||||
|
||||
val input = readInput("aoc2024/Day15")
|
||||
part1(input).println()
|
||||
part2(input).println()
|
||||
}
|
Loading…
Reference in New Issue
Block a user