mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 22:09:50 +01:00
57 lines
1.8 KiB
Scala
57 lines
1.8 KiB
Scala
import scala.io.StdIn.readLine
|
|
import java.time.{LocalDate, LocalTime}
|
|
import java.time.format.DateTimeFormatter
|
|
|
|
val fmt: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd kk:mm")
|
|
|
|
case class Entry(shiftDate: LocalDate, time: LocalTime, id: Option[Int], sleep: Option[Boolean])
|
|
|
|
def parseEntry(input: String): Entry = {
|
|
"\\[([^\\]]+)\\] ([^ ]+) ([^ ]+)".r.findFirstMatchIn(input).map {
|
|
m =>
|
|
val ts = fmt.parse(m.group(1))
|
|
val time = LocalTime.from(ts)
|
|
val shiftDate = time match {
|
|
case t if t.getHour == 23 => LocalDate.from(ts).plusDays(1L)
|
|
case _ => LocalDate.from(ts)
|
|
}
|
|
|
|
m.group(2) match {
|
|
case "Guard" => Entry(shiftDate, time, Some(m.group(3).drop(1).toInt), None)
|
|
case "falls" => Entry(shiftDate, time, None, Some(true))
|
|
case "wakes" => Entry(shiftDate, time, None, Some(false))
|
|
}
|
|
}.get
|
|
}
|
|
|
|
case class Sleep(id: Int, begin: LocalTime, end: LocalTime)
|
|
|
|
def buildSleeps(input: List[Entry]): List[Sleep] = {
|
|
val guardNb = input.filter(_.id.nonEmpty).map(_.id.get).head
|
|
val sleepCycles = input.filter(e => e.sleep.nonEmpty).map(e => e.time -> e.sleep.get).sortBy(_._1.toSecondOfDay)
|
|
|
|
(sleepCycles.filter(_._2).map(_._1) zip sleepCycles.filterNot(_._2).map(_._1))
|
|
.map(s => Sleep(guardNb, s._1, s._2))
|
|
}
|
|
|
|
val entries = Iterator
|
|
.continually(readLine)
|
|
.takeWhile(_ != null)
|
|
.map(parseEntry)
|
|
.toList
|
|
|
|
val sleeps = entries.groupBy(_.shiftDate)
|
|
.flatMap { case (k, v) => buildSleeps(v) }
|
|
|
|
val res = sleeps
|
|
.flatMap ( s => s.begin.getMinute.to(s.end.getMinute - 1).map(m => m -> s.id))
|
|
.groupBy(identity)
|
|
.mapValues(_.size)
|
|
.toList
|
|
.sortBy(_._2)
|
|
.last
|
|
|
|
println(s"Guard ${res._1._1} slept during minute ${res._1._2}, ${res._2} times.")
|
|
|
|
println(s"Result: ${res._1._1 * res._1._2}")
|