Skip to content

Commit

Permalink
Day 24: Blizzard Basin
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemient committed Dec 24, 2022
1 parent 8638b12 commit 887f501
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ Development occurs in language-specific directories:
|[Day21.hs](hs/src/Day21.hs)|[Day21.kt](kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day21.kt)|[day21.py](py/aoc2022/day21.py)|[day21.rs](rs/src/day21.rs)|
|[Day22.hs](hs/src/Day22.hs)|[Day22.kt](kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day22.kt)|[day22.py](py/aoc2022/day22.py)|[day22.rs](rs/src/day22.rs)|
|[Day23.hs](hs/src/Day23.hs)|[Day23.kt](kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day23.kt)|[day23.py](py/aoc2022/day23.py)|[day23.rs](rs/src/day23.rs)|
|[Day24.hs](hs/src/Day24.hs)|
|[Day24.hs](hs/src/Day24.hs)|[Day24.kt](kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day24.kt)|
56 changes: 56 additions & 0 deletions kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day24.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.github.ephemient.aoc2022

import kotlin.math.abs

@Day
class Day24(private val lines: List<String>) {
private val start = lines.first().indexOf('.') to 0
private val end = lines.last().lastIndexOf('.') to lines.lastIndex

@Suppress("ComplexCondition")
private fun isFree(x: Int, y: Int, time: Int): Boolean {
if (x <= 0 || y <= 0 || y >= lines.lastIndex || x >= lines.getOrElse(y) { "" }.lastIndex) {
return (lines.getOrNull(y)?.getOrNull(x) ?: '#') == '.'
}
return lines[y][(x - 1 + time).mod(lines[y].length - 2) + 1] != '<' &&
lines[y][(x - 1 - time).mod(lines[y].length - 2) + 1] != '>' &&
lines[(y - 1 + time).mod(lines.size - 2) + 1][x] != '^' &&
lines[(y - 1 - time).mod(lines.size - 2) + 1][x] != 'v'
}

private fun search(start: IntPair, end: IntPair, startTime: Int = 0): Int {
val (endX, endY) = end
val queue = PriorityQueue(compareBy(IndexedValue<IndexedValue<IntPair>>::index))
queue.add(IndexedValue(0, IndexedValue(startTime, start)))
val seen = mutableSetOf<IndexedValue<IntPair>>()
while (!queue.isEmpty()) {
val entry = queue.remove().value
if (!seen.add(entry)) continue
val (time, position) = entry
if (position == end) return time
val (x, y) = position
if (isFree(x, y, time + 1)) {
queue.add(IndexedValue(time + abs(x - endX) + abs(y - endY), IndexedValue(time + 1, x to y)))
}
if (isFree(x - 1, y, time + 1)) {
queue.add(IndexedValue(time + abs(x - 1 - endX) + abs(y - endY), IndexedValue(time + 1, x - 1 to y)))
}
if (isFree(x + 1, y, time + 1)) {
queue.add(IndexedValue(time + abs(x + 1 - endX) + abs(y - endY), IndexedValue(time + 1, x + 1 to y)))
}
if (isFree(x, y - 1, time + 1)) {
queue.add(IndexedValue(time + abs(x - endX) + abs(y - 1 - endY), IndexedValue(time + 1, x to y - 1)))
}
if (isFree(x, y + 1, time + 1)) {
queue.add(IndexedValue(time + abs(x - endX) + abs(y + 1 - endY), IndexedValue(time + 1, x to y + 1)))
}
}
throw NoSuchElementException()
}

@Day.Part
fun part1(): Int = search(start, end)

@Day.Part
fun part2(): Int = search(start, end, search(end, start, search(start, end)))
}
16 changes: 16 additions & 0 deletions kt/src/commonTest/kotlin/com/github/ephemient/aoc2022/Day24Test.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.github.ephemient.aoc2022

import kotlin.test.Test
import kotlin.test.assertEquals

class Day24Test {
@Test
fun part1() {
assertEquals(18, Day24(getTestInput(24)).part1())
}

@Test
fun part2() {
assertEquals(54, Day24(getTestInput(24)).part2())
}
}
6 changes: 6 additions & 0 deletions kt/src/jvmTest/resources/day24.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#.######
#>>.<^<#
#.<..<<#
#>v.><>#
#<^v^^>#
######.#

0 comments on commit 887f501

Please sign in to comment.