Skip to content

Commit

Permalink
Day 21
Browse files Browse the repository at this point in the history
  • Loading branch information
WVerlaek committed Dec 22, 2023
1 parent 34dd626 commit 60d4327
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
84 changes: 84 additions & 0 deletions src/main/kotlin/y23/Day21.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package y23

import common.puzzle.solvePuzzle
import common.puzzle.Input
import common.puzzle.Puzzle
import common.datastructures.*
import common.ext.*
import common.util.*
import java.util.*
import kotlin.math.*
import kotlin.system.exitProcess


fun main() = solvePuzzle(year = 2023, day = 21, dryRun = true) { Day21(it) }

class Day21(val input: Input) : Puzzle {

private lateinit var start: Point
private val grid = Grid(input.lines.size, input.lines[0].length) { r, c ->
when (input.lines[r][c]) {
'.' -> false
'#' -> true
'S' -> {
start = Point(c, r)
false
}
else -> error("unknown char")
}
}

fun reachablePlots(steps: Int, grid: Grid<Boolean> = this.grid, start: Point = this.start): Int {
var plots = listOf(start)

repeat(steps) {
plots = plots.flatMap { p ->
directions.mapNotNull { (dx, dy) ->
val neigh = Point(p.col + dx, p.row + dy)
if (!grid.withinBounds(neigh.row, neigh.col)) {
return@mapNotNull null
}
if (grid[neigh.row][neigh.col].value) {
return@mapNotNull null
}
return@mapNotNull neigh
}
}.distinct()
}

return plots.size
}

override fun solveLevel1(): Any {
return reachablePlots(64)
}

override fun solveLevel2(): Any {
// 65 <- S -> 65 (131 total)
// (26501365 - 65) / 131 = 202300

// start = [65,65]

// 4 diamond corners
return reachablePlots(130, grid, Point(0, 65)) +
reachablePlots(130, grid, Point(130, 65)) +
reachablePlots(130, grid, Point(65, 0)) +
reachablePlots(130, grid, Point(65, 130)) +

// Edges (large area)
202299L * reachablePlots(131+64, grid, Point(130, 130)) +
202299L * reachablePlots(131+64, grid, Point(0, 130)) +
202299L * reachablePlots(131+64, grid, Point(0, 0)) +
202299L * reachablePlots(131+64, grid, Point(130, 0)) +

// Edges (small area)
202300L * reachablePlots(64, grid, Point(130, 130)) +
202300L * reachablePlots(64, grid, Point(0, 130)) +
202300L * reachablePlots(64, grid, Point(0, 0)) +
202300L * reachablePlots(64, grid, Point(130, 0)) +

// Full squares
(202299L * 202299L) * reachablePlots(141, grid, start) + // odd
(202300L * 202300L) * reachablePlots(140, grid, start) // even
}
}
33 changes: 33 additions & 0 deletions src/test/kotlin/y23/Day21Test.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package y23

import common.puzzle.Input
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

internal class Day21Test {
private val sample = Input("""
...........
.....###.#.
.###.##..#.
..#.#...#..
....#.#....
.##..S####.
.##..#...#.
.......##..
.##.#.####.
.##..##.##.
...........
""".trimIndent())

private val day = Day21(sample)

@Test
fun solveLevel1() {
assertEquals(16, day.reachablePlots(6))
}

@Test
fun solveLevel2() {
// Level 2 solution doesn't work on sample input.
}
}

0 comments on commit 60d4327

Please sign in to comment.