Improved day 5 solution
This commit is contained in:
parent
e2ab0d7b37
commit
5dde3b6445
|
@ -8,55 +8,39 @@ import tf.bug.aoc.Day
|
||||||
|
|
||||||
object Day5 extends Day:
|
object Day5 extends Day:
|
||||||
|
|
||||||
case class Seat(row: Int, col: Int) {
|
|
||||||
def id = row * 8 + col
|
|
||||||
}
|
|
||||||
|
|
||||||
object Seat {
|
|
||||||
implicit val seatOrdering: Ordering[Seat] = Ordering.by(_.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override def part1[F[_]: Async]: Pipe[F, String, String] =
|
override def part1[F[_]: Async]: Pipe[F, String, String] =
|
||||||
(lines: Stream[F, String]) => {
|
(lines: Stream[F, String]) => {
|
||||||
lines.through(seats[F])
|
lines.through(seats[F])
|
||||||
.map(_.id)
|
|
||||||
.fold1(_.max(_))
|
.fold1(_.max(_))
|
||||||
.map(_.show)
|
.map(_.show)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class SearchState(min: Int, max: Int, sum: Int)
|
||||||
|
|
||||||
override def part2[F[_]: Async]: Pipe[F, String, String] =
|
override def part2[F[_]: Async]: Pipe[F, String, String] =
|
||||||
(lines: Stream[F, String]) => {
|
(lines: Stream[F, String]) => {
|
||||||
val sortedSeats: F[SortedSet[Seat]] =
|
lines
|
||||||
lines.through(seats[F])
|
.filter(_.nonEmpty)
|
||||||
.compile.to(Collector.supportsFactory(SortedSet))
|
.through(seats[F])
|
||||||
val pairs: Stream[F, (Seat, Seat)] =
|
.fold(SearchState(Int.MaxValue, Int.MinValue, 0)) {
|
||||||
Stream.eval(sortedSeats)
|
case (SearchState(min, max, sum), seat) =>
|
||||||
.flatMap(seats => Stream.fromIterator[F](seats.sliding(2).map(set => (set.min, set.max)), 1))
|
val newMin = seat.min(min)
|
||||||
val gaps: Stream[F, Int] = pairs.collect {
|
val newMax = seat.max(max)
|
||||||
case (a, b) if a.id + 1 == b.id - 1 => a.id + 1
|
val newSum = sum + seat
|
||||||
}
|
SearchState(newMin, newMax, newSum)
|
||||||
gaps.map(_.show)
|
}
|
||||||
|
.map {
|
||||||
|
case SearchState(min, max, sum) =>
|
||||||
|
val range = (max - min) + 1
|
||||||
|
val total = ((max + min) * range) / 2
|
||||||
|
total - sum
|
||||||
|
}
|
||||||
|
.map(_.show)
|
||||||
}
|
}
|
||||||
|
|
||||||
def seats[F[_]: Async]: Pipe[F, String, Seat] =
|
def seats[F[_]: Async]: Pipe[F, String, Int] =
|
||||||
(lines: Stream[F, String]) => {
|
_.map(_.foldLeft(0) {
|
||||||
lines
|
case (id, ch) =>
|
||||||
.map { s =>
|
val newBit = ((ch & 4) >>> 2) ^ 1
|
||||||
val (row, col) = s.splitAt(7)
|
(id * 2) + newBit
|
||||||
val rowN = row.zipWithIndex.foldLeft(0) {
|
})
|
||||||
case (n, ('F', _)) =>
|
|
||||||
n
|
|
||||||
case (n, ('B', i)) =>
|
|
||||||
val range = 1 << (6 - i)
|
|
||||||
n + range
|
|
||||||
}
|
|
||||||
val colN = col.zipWithIndex.foldLeft(0) {
|
|
||||||
case (n, ('L', _)) =>
|
|
||||||
n
|
|
||||||
case (n, ('R', i)) =>
|
|
||||||
val range = 1 << (2 - i)
|
|
||||||
n + range
|
|
||||||
}
|
|
||||||
Seat(rowN, colN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue