Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Day 14: Restroom Redoubt #9

Merged
merged 1 commit into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading