Skip to content

Commit

Permalink
Day 14: Restroom Redoubt
Browse files Browse the repository at this point in the history
  • Loading branch information
andilau committed Dec 14, 2024
1 parent ba42df5 commit e834bb8
Show file tree
Hide file tree
Showing 5 changed files with 606 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ Advent of Code is an Advent calendar of small programming puzzles by [Eric Wastl
- Day 4: [Ceres Search](https://adventofcode.com/2024/day/4) -- [Day4.kt](https://github.com/andilau/advent-of-code-2024/blob/main/src/main/kotlin/days/Day4.kt)
- Day 5: [Print Queue](https://adventofcode.com/2024/day/5) -- [Day5.kt](https://github.com/andilau/advent-of-code-2024/blob/main/src/main/kotlin/days/Day5.kt)
- Day 7: [Bridge Repair](https://adventofcode.com/2024/day/7) -- [Day7.kt](https://github.com/andilau/advent-of-code-2024/blob/main/src/main/kotlin/days/Day7.kt)
- Day 8: [Resonant Collinearity](https://adventofcode.com/2024/day/8) -- [Day7.kt](https://github.com/andilau/advent-of-code-2024/blob/main/src/main/kotlin/days/Day8.kt)
- Day 8: [Resonant Collinearity](https://adventofcode.com/2024/day/8) -- [Day8.kt](https://github.com/andilau/advent-of-code-2024/blob/main/src/main/kotlin/days/Day8.kt)
- Day 14: [Restroom Redoubt](https://adventofcode.com/2024/day/14) -- [Day14.kt](https://github.com/andilau/advent-of-code-2024/blob/main/src/main/kotlin/days/Day14.kt)

### Features

Expand Down
69 changes: 69 additions & 0 deletions src/main/kotlin/days/Day14.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package days

@AdventOfCodePuzzle(
name = "Restroom Redoubt",
url = "https://adventofcode.com/2024/day/14",
date = Date(day = 14, year = 2024)
)
class Day14(val input: List<String>) : Puzzle {

val robots: List<Robot> = input.map { line -> Robot.from(line) }

val bounds = if (input.size < 100) Point(11, 7) else Point(101, 103)

override fun partOne() = robots
.map { it.move(100).bounds(bounds) }
.groupingBy() { quadrant(it.position) }.eachCount()
.filter { it.key != 0 }
.values
.fold(1L) { a, b -> a * b }

override fun partTwo(): Int =
generateSequence(0) { it + 1 }
.firstNotNullOfOrNull { seconds ->
val count = robots
.map { it.move(seconds).bounds(bounds).position }
.toSet().count()
if (count == input.size) seconds else null
} ?: error("No solution found")

fun draw(robots: List<Robot>) {
(0..bounds.y).forEach { y ->
(0..bounds.x).map { x ->
if (robots.any { it.position == Point(x, y) }) "#" else "."
}.joinToString("").also { println(it) }
}
}

private fun quadrant(p: Point): Int =
when { // top left, top right, bottom left, bottom right
p.x in 0..<(bounds.x / 2) && p.y in 0..<(bounds.y / 2) -> 1 // top left
p.x in (bounds.x / 2 + 1)..bounds.x && p.y in 0..<(bounds.y / 2) -> 2 // top right
p.x in 0..<(bounds.x / 2) && p.y in (bounds.y / 2 + 1)..bounds.y -> 3 // bottom left
p.x in (bounds.x / 2 + 1)..bounds.x && p.y in (bounds.y / 2 + 1)..bounds.y -> 4 // bottom right
else -> 0
}

data class Robot(val position: Point, val velocity: Point) {
fun move(times: Int) = Robot(position + (velocity * times), velocity)
fun bounds(bounds: Point) = Robot(position.moveToBounds(bounds), velocity)

companion object {
fun from(line: String): Robot {
val (p, v) = line.split(" ")
val position = p.removePrefix("p=").split(",").map { it.toInt() }
val velocity = v.removePrefix("v=").split(",").map { it.toInt() }
return Robot(Point(position[0], position[1]), Point(velocity[0], velocity[1]))
}
}
}

data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point) = Point(x + other.x, y + other.y)
operator fun minus(other: Point) = Point(x - other.x, y - other.y)
operator fun times(o: Int) = Point(x * o, y * o)

fun moveToBounds(bounds: Point) = Point(x.mod(bounds.x), y.mod(bounds.y))
}

}
Loading

0 comments on commit e834bb8

Please sign in to comment.