55 lines
1.7 KiB
Scala
55 lines
1.7 KiB
Scala
|
package tf.bug.aoc
|
||
|
|
||
|
import cats.effect._
|
||
|
import cats.effect.std.Console
|
||
|
import cats.syntax.all._
|
||
|
import java.nio.charset.StandardCharsets
|
||
|
import fs2._
|
||
|
|
||
|
object Main extends IOApp:
|
||
|
|
||
|
def years: Map[Int, Year] = Map(
|
||
|
2020 -> y2020.y2020,
|
||
|
)
|
||
|
|
||
|
override def run(args: List[String]): IO[ExitCode] =
|
||
|
val year: IO[Year] = selectYear[IO]
|
||
|
val day: IO[Day] = year >>= selectDay[IO]
|
||
|
val part: IO[Pipe[IO, String, String]] = day >>= selectPart[IO]
|
||
|
part.flatMap { p =>
|
||
|
io.stdinUtf8[IO](1024)
|
||
|
.through(text.lines)
|
||
|
.takeWhile(_.nonEmpty)
|
||
|
.through(p)
|
||
|
.through(io.stdoutLines(StandardCharsets.UTF_8))
|
||
|
.compile.drain
|
||
|
}.as(ExitCode.Success)
|
||
|
|
||
|
def selectYear[F[_]: Sync: Console]: F[Year] =
|
||
|
val ask = Sync[F].delay(print("Select year: "))
|
||
|
val receive = Console[F].readLine
|
||
|
val year: F[Option[Year]] = (ask >> receive).map(_.toIntOption >>= years.get)
|
||
|
year.flatMap {
|
||
|
case Some(year) => year.pure[F]
|
||
|
case None => selectYear[F]
|
||
|
}
|
||
|
|
||
|
def selectDay[F[_]: Sync: Console](year: Year): F[Day] =
|
||
|
val ask = Sync[F].delay(print("Select day: "))
|
||
|
val receive = Console[F].readLine
|
||
|
val day: F[Option[Day]] = (ask >> receive).map(_.toIntOption >>= year.days.get)
|
||
|
day.flatMap {
|
||
|
case Some(day) => day.pure[F]
|
||
|
case None => selectDay[F](year)
|
||
|
}
|
||
|
|
||
|
def selectPart[F[_]: Sync: Console](day: Day): F[Pipe[F, String, String]] =
|
||
|
val ask = Sync[F].delay(print("Select part: "))
|
||
|
val receive = Console[F].readLine
|
||
|
val part: F[Option[Int]] = (ask >> receive).map(_.toIntOption)
|
||
|
part.flatMap {
|
||
|
case Some(1) => day.part1[F].pure[F]
|
||
|
case Some(2) => day.part2[F].pure[F]
|
||
|
case _ => selectPart[F](day)
|
||
|
}
|