Skip to content

Commit

Permalink
[2024/25] Code Chronicle (Part 1)
Browse files Browse the repository at this point in the history
  • Loading branch information
pfolta committed Dec 27, 2024
1 parent c842854 commit 91fe13f
Show file tree
Hide file tree
Showing 9 changed files with 4,140 additions and 11 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
| 2021 |||||||||||| ||| | | | | | | | | | | | 26 |
| 2022 |||||||||||||| | | | | | | || | | || 28 |
| 2023 |||||||| | | | | | | | | | | | | | | | | | | 12 |
| 2024 ||||||||||||||| |||||| || | | | 39 |
| 2024 ||||||||||||||| |||||| || | | | 40 |

## 🛷 How to run

Expand Down Expand Up @@ -184,6 +184,7 @@ e.g. `HandyHaversacks`)*
| | 19 | [Linen Layout](https://adventofcode.com/2024/day/19) | [[Code](src/main/kotlin/adventofcode/year2024/Day19LinenLayout.kt)] [[Test](src/test/kotlin/adventofcode/year2024/Day19LinenLayoutSpec.kt)] | `267` | `796449099271652` |
| | 20 | [Race Condition](https://adventofcode.com/2024/day/20) | [[Code](src/main/kotlin/adventofcode/year2024/Day20RaceCondition.kt)] [[Test](src/test/kotlin/adventofcode/year2024/Day20RaceConditionSpec.kt)] | `1426` | `1000697` |
| | 22 | [Monkey Market](https://adventofcode.com/2024/day/22) | [[Code](src/main/kotlin/adventofcode/year2024/Day22MonkeyMarket.kt)] [[Test](src/test/kotlin/adventofcode/year2024/Day22MonkeyMarketSpec.kt)] | `20332089158` | `2191` |
| | 25 | [Code Chronicle](https://adventofcode.com/2024/day/25) | [[Code](src/main/kotlin/adventofcode/year2024/Day25CodeChronicle.kt)] [[Test](src/test/kotlin/adventofcode/year2024/Day25CodeChronicleSpec.kt)] | `3608` | |

## 🕯️ Useful commands

Expand Down
18 changes: 16 additions & 2 deletions src/main/kotlin/adventofcode/common/spatial/Grid2d.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package adventofcode.common.spatial

data class Grid2d<T>(val values: List<List<T>>) {
val points = values.flatMapIndexed { y, row -> List(row.size) { x -> Point2d(x, y) } }
/** Set of points contained in this grid. */
val points = values.flatMapIndexed { y, row -> List(row.size) { x -> Point2d(x, y) } }.toSet()

/** `true` for a square grid, `false` otherwise. */
val isSquare: Boolean = values.all { row -> row.size == values.size }
Expand All @@ -19,7 +20,19 @@ data class Grid2d<T>(val values: List<List<T>>) {
override fun toString(): String = values.joinToString("\n") { row -> row.toString() }

/** Returns the number of columns for a given row in the grid. */
fun colsInRow(row: Int) = values[row].size
fun columnsInRow(row: Int) = values[row].size

/** Returns the row of elements at the given row index. */
fun rowAt(index: Int): List<T> = values[index]

/** Returns the column of elements at the given column index. */
fun columnAt(index: Int): List<T> = values.map { row -> row[index] }

/** Syntactic sugar for nested `values` list. */
fun rows(): List<List<T>> = values

/** Returns all the columns of the grid. */
fun columns(): List<List<T>> = rotate().values.map(List<T>::reversed)

/** Returns `true` if the grid contains `value`. */
operator fun contains(value: T): Boolean = values.flatten().contains(value)
Expand Down Expand Up @@ -73,6 +86,7 @@ data class Grid2d<T>(val values: List<List<T>>) {
}

companion object {
/** Create a new `Grid2d` from a `String` where each point is a character of that string. */
operator fun invoke(values: String) = Grid2d(values.lines().map(String::toList))
}
}
9 changes: 3 additions & 6 deletions src/main/kotlin/adventofcode/common/spatial/Point2d.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ data class Point2d(
val x: Long,
val y: Long,
) {
/** Alternative constructor to allow other Number types as coordinates, e.g. `Int`s. */
constructor(x: Number, y: Number) : this(x.toLong(), y.toLong())

/**
* Pretty formatted String representation.
*
* (0, 1)
*/
/** Pretty formatted String representation: (0, 1) */
override fun toString(): String = "($x, $y)"

/** Add two points together by adding their x and y coordinates. */
Expand Down Expand Up @@ -41,7 +38,7 @@ data class Point2d(
.map { direction -> this + direction }
.toSet()

/** Returns the manhattan distance between two points. */
/** Returns the Manhattan distance between two points. */
infix fun distanceTo(other: Point2d): Long = (x - other.x).absoluteValue + (y - other.y).absoluteValue

companion object {
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/adventofcode/year2024/Day04CeresSearch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Day04CeresSearch(customInput: PuzzleInput? = null) : Puzzle(customInput) {
val length = xmas.length

return (0 until rows).flatMap { row ->
(0 until colsInRow(row)).flatMap { col ->
(0 until columnsInRow(row)).flatMap { col ->
val horizontal = (0 until length).map { y -> Point2d(row, col + y) }.filter { point -> point in this }
val vertical = (0 until length).map { x -> Point2d(row + x, col) }.filter { point -> point in this }
val rightDiagonal = (0 until length).map { d -> Point2d(row + d, col + d) }.filter { point -> point in this }
Expand All @@ -37,7 +37,7 @@ class Day04CeresSearch(customInput: PuzzleInput? = null) : Puzzle(customInput) {
val length = mas.length

return (0..rows - length).flatMap { row ->
(0..colsInRow(row) - length).map { col ->
(0..columnsInRow(row) - length).map { col ->
val topDiagonal = (0 until length).map { d -> Point2d(row + d, col + d) }
val bottomDiagonal = (0 until length).map { d -> Point2d(row + length - 1 - d, col + d) }

Expand Down
35 changes: 35 additions & 0 deletions src/main/kotlin/adventofcode/year2024/Day25CodeChronicle.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package adventofcode.year2024

import adventofcode.Puzzle
import adventofcode.PuzzleInput
import adventofcode.common.cartesianProduct
import adventofcode.common.spatial.Grid2d

class Day25CodeChronicle(customInput: PuzzleInput? = null) : Puzzle(customInput) {
private val schematics by lazy { input.split("\n\n").map { Grid2d(it) } }
private val locks by lazy {
schematics
.filter { schematic -> schematic.rowAt(0).all { it == FILLED } && schematic.rowAt(schematic.rows - 1).all { it == EMPTY } }
.map { schematic -> Grid2d(schematic.values.drop(1).dropLast(1)) }
.toSet()
}
private val keys by lazy {
schematics
.map { schematic -> Grid2d(schematic.values.drop(1).dropLast(1)) }
.minus(locks)
.toSet()
}

override fun partOne() =
listOf(locks, keys)
.cartesianProduct()
.map { (lock, key) -> lock.toHeights().zip(key.toHeights()) { lockHeight, keyHeight -> lockHeight + keyHeight } }
.count { lockKeyPair -> lockKeyPair.all { height -> height <= 5 } }

companion object {
private const val FILLED = '#'
private const val EMPTY = '.'

private fun Grid2d<Char>.toHeights(): List<Int> = columns().map { column -> column.count { it == FILLED } }
}
}
Loading

0 comments on commit 91fe13f

Please sign in to comment.