Day 3
This commit is contained in:
parent
b9bf5023eb
commit
457f034d73
6 changed files with 60 additions and 12 deletions
|
@ -5,5 +5,5 @@ import cats.effect._
|
|||
import fs2._
|
||||
|
||||
trait Day:
|
||||
def part1[F[_]: Sync]: Pipe[F, String, String]
|
||||
def part2[F[_]: Sync]: Pipe[F, String, String]
|
||||
def part1[F[_]: Async]: Pipe[F, String, String]
|
||||
def part2[F[_]: Async]: Pipe[F, String, String]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package tf.bug.aoc
|
||||
|
||||
import cats._
|
||||
import cats.effect._
|
||||
import cats.effect.std.Console
|
||||
import cats.syntax.all._
|
||||
|
@ -25,8 +26,8 @@ object Main extends IOApp:
|
|||
.compile.drain
|
||||
}.as(ExitCode.Success)
|
||||
|
||||
def selectYear[F[_]: Sync: Console]: F[Year] =
|
||||
val ask = Sync[F].delay(print("Select year: "))
|
||||
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 {
|
||||
|
@ -34,8 +35,8 @@ object Main extends IOApp:
|
|||
case None => selectYear[F]
|
||||
}
|
||||
|
||||
def selectDay[F[_]: Sync: Console](year: Year): F[Day] =
|
||||
val ask = Sync[F].delay(print("Select day: "))
|
||||
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 {
|
||||
|
@ -43,8 +44,8 @@ object Main extends IOApp:
|
|||
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: "))
|
||||
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 {
|
||||
|
|
|
@ -10,10 +10,10 @@ import tf.bug.aoc.Day
|
|||
|
||||
object Day1 extends Day:
|
||||
|
||||
override def part1[F[_]: Sync]: Pipe[F, String, String] =
|
||||
override def part1[F[_]: Async]: Pipe[F, String, String] =
|
||||
parts[F](2)
|
||||
|
||||
override def part2[F[_]: Sync]: Pipe[F, String, String] =
|
||||
override def part2[F[_]: Async]: Pipe[F, String, String] =
|
||||
parts[F](3)
|
||||
|
||||
def parts[F[_]: Sync](nums: Int): Pipe[F, String, String] =
|
||||
|
|
|
@ -23,13 +23,13 @@ object Day2 extends Day:
|
|||
Entry(policy, password)
|
||||
}
|
||||
|
||||
override def part1[F[_]: Sync]: Pipe[F, String, String] =
|
||||
override def part1[F[_]: Async]: Pipe[F, String, String] =
|
||||
parts[F] { ent =>
|
||||
val charCount = ent.password.count(_ == ent.policy.letter)
|
||||
ent.policy.min <= charCount && charCount <= ent.policy.max
|
||||
}
|
||||
|
||||
override def part2[F[_]: Sync]: Pipe[F, String, String] =
|
||||
override def part2[F[_]: Async]: Pipe[F, String, String] =
|
||||
parts[F] { ent =>
|
||||
val a = ent.policy.min <= ent.password.length && ent.password.charAt(ent.policy.min - 1) == ent.policy.letter
|
||||
val b = ent.policy.max <= ent.password.length && ent.password.charAt(ent.policy.max - 1) == ent.policy.letter
|
||||
|
|
46
core/src/main/scala/tf/bug/aoc/y2020/Day3.scala
Normal file
46
core/src/main/scala/tf/bug/aoc/y2020/Day3.scala
Normal file
|
@ -0,0 +1,46 @@
|
|||
package tf.bug.aoc.y2020
|
||||
|
||||
import cats.effect._
|
||||
import cats.syntax.all._
|
||||
import fs2._
|
||||
import tf.bug.aoc.Day
|
||||
|
||||
object Day3 extends Day:
|
||||
|
||||
case class Path(x: Int, treeCount: Long)
|
||||
|
||||
override def part1[F[_]: Async]: Pipe[F, String, String] =
|
||||
_.through(checkSlope[F](3, 1)).map(_.show)
|
||||
|
||||
override def part2[F[_]: Async]: Pipe[F, String, String] =
|
||||
(lines: Stream[F, String]) => {
|
||||
val pipes: Vector[Pipe[F, String, Long]] = Vector(
|
||||
checkSlope[F](1, 1),
|
||||
checkSlope[F](3, 1),
|
||||
checkSlope[F](5, 1),
|
||||
checkSlope[F](7, 1),
|
||||
checkSlope[F](1, 2),
|
||||
)
|
||||
val broadcast: Stream[F, String] => Stream[F, Stream[F, String]] = concurrent.Broadcast[F, String](pipes.size)
|
||||
val channels: Stream[F, Stream[F, String]] = lines.through(broadcast).take(pipes.size)
|
||||
val results: Stream[F, Long] = channels.zipWithIndex.map {
|
||||
case (channel, ind) =>
|
||||
val pipe = pipes(ind.toInt)
|
||||
channel.through(pipe)
|
||||
}.parJoin(pipes.size)
|
||||
results.fold(1L)(_ * _).map(_.show)
|
||||
}
|
||||
|
||||
def checkSlope[F[_]](right: Int, down: Int): Pipe[F, String, Long] =
|
||||
(lines: Stream[F, String]) => {
|
||||
lines.chunkN(down, true).fold(Path(0, 0L)) {
|
||||
case (Path(x, numTrees), group) =>
|
||||
group.head match {
|
||||
case Some(line) =>
|
||||
val isTree = line.charAt(x % line.length) == '#'
|
||||
Path(x + right, if(isTree) numTrees + 1L else numTrees)
|
||||
case None =>
|
||||
Path(x, numTrees)
|
||||
}
|
||||
}.map(_.treeCount)
|
||||
}
|
|
@ -6,4 +6,5 @@ object y2020 extends Year:
|
|||
override def days: Map[Int, Day] = Map(
|
||||
1 -> Day1,
|
||||
2 -> Day2,
|
||||
3 -> Day3,
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue