This commit is contained in:
Paul-Henri Froidmont 2022-12-18 00:05:08 +01:00
parent 2cda8f7b94
commit cc7c5b88f0
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
2 changed files with 101 additions and 0 deletions

76
aoc/src/Day15.scala Normal file
View 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