Day 15
This commit is contained in:
parent
2cda8f7b94
commit
cc7c5b88f0
2 changed files with 101 additions and 0 deletions
76
aoc/src/Day15.scala
Normal file
76
aoc/src/Day15.scala
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import scala.io.Source
|
||||
import scala.util.chaining.*
|
||||
|
||||
object Day15 extends App:
|
||||
|
||||
val input = Source
|
||||
.fromURL(getClass.getResource("day15Input.txt"))
|
||||
.mkString
|
||||
.split('\n')
|
||||
.map(
|
||||
_.drop(12)
|
||||
.split(": closest beacon is at x=")
|
||||
.map(_.split(", y=").map(_.toInt))
|
||||
).map { case Array(Array(sX, sY), Array(bX, bY)) =>
|
||||
((sX, sY), (bX, bY))
|
||||
}.toMap
|
||||
|
||||
type Point = (Int, Int)
|
||||
|
||||
extension (point: Point)
|
||||
def x = point._1
|
||||
def y = point._2
|
||||
|
||||
def manhattanDistance(to: Point): Int = (x - to.x).abs + (y - to.y).abs
|
||||
|
||||
val beacons = input.values.toList
|
||||
|
||||
val sensorsWithDistance = input.map { case ((sX, sY), (bX, bY)) =>
|
||||
((sX, sY), (sX, sY).manhattanDistance(bX, bY))
|
||||
}.toMap
|
||||
|
||||
val xMin = sensorsWithDistance.map { case ((x, _), distance) => x - distance }.min
|
||||
val xMax = sensorsWithDistance.map { case ((x, _), distance) => x + distance }.max
|
||||
val yMin = sensorsWithDistance.map { case ((_, y), distance) => y - distance }.min
|
||||
val yMax = sensorsWithDistance.map { case ((_, y), distance) => y + distance }.max
|
||||
|
||||
val part1 = (for x <- xMin to xMax yield (x, 2000000))
|
||||
.filterNot(beacons.contains)
|
||||
.filter(point =>
|
||||
sensorsWithDistance.exists { case (sensor, distance) =>
|
||||
point.manhattanDistance(sensor) <= distance
|
||||
}
|
||||
).length
|
||||
|
||||
println("Part 1:")
|
||||
println(part1)
|
||||
|
||||
val part2Bound = 4000000
|
||||
|
||||
val posiblePosition = LazyList.iterate((0, 0))(point =>
|
||||
if point.x >= part2Bound then (0, point.y + 1)
|
||||
else
|
||||
sensorsWithDistance
|
||||
.find { case (sensor, distance) =>
|
||||
point.manhattanDistance(sensor) <= distance
|
||||
}.map { case (sensor, distance) =>
|
||||
(
|
||||
point.x + (sensor.x - point.x) + (distance + 1) - ((sensor.y - point.y).abs),
|
||||
point.y
|
||||
)
|
||||
}.getOrElse((point.x + 1, point.y))
|
||||
)
|
||||
|
||||
val beaconPosition = posiblePosition
|
||||
.filter(point => point.x < part2Bound && point.y < part2Bound)
|
||||
.filterNot(point =>
|
||||
sensorsWithDistance.exists { case (sensor, distance) =>
|
||||
point.manhattanDistance(sensor) <= distance
|
||||
}
|
||||
)
|
||||
.head
|
||||
|
||||
val part2 = beaconPosition.x * 4000000L + beaconPosition.y
|
||||
println("Part 2:")
|
||||
println(part2)
|
||||
end Day15
|
||||
Loading…
Add table
Add a link
Reference in a new issue