aoc/core/src/main/scala/tf/bug/aoc/Main.scala

61 lines
1.7 KiB
Scala

package tf.bug.aoc
import cats._
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)
.through(p)
.through(io.stdoutLines(StandardCharsets.UTF_8))
.compile.drain
}.as(ExitCode.Success)
}
def selectYear[F[_]: Monad: Console]: F[Year] = {
val ask = Console[F].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[_]: Monad: Console](year: Year): F[Day] = {
val ask = Console[F].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[_]: Async: Console](day: Day): F[Pipe[F, String, String]] = {
val ask = Console[F].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)
}
}
}