Day2
This commit is contained in:
parent
1f224d4ed6
commit
b9bf5023eb
|
@ -8,5 +8,6 @@ lazy val core = (project in file("core")).settings(
|
|||
"org.typelevel" %% "cats-effect" % "3.0.0-M4",
|
||||
"co.fs2" %% "fs2-core" % "3.0.0-M6",
|
||||
"co.fs2" %% "fs2-io" % "3.0.0-M6",
|
||||
"org.typelevel" %% "cats-parse" % "0.1-31-923a513",
|
||||
),
|
||||
)
|
||||
|
|
|
@ -10,10 +10,10 @@ import tf.bug.aoc.Day
|
|||
|
||||
object Day1 extends Day:
|
||||
|
||||
def part1[F[_]: Sync]: Pipe[F, String, String] =
|
||||
override def part1[F[_]: Sync]: Pipe[F, String, String] =
|
||||
parts[F](2)
|
||||
|
||||
def part2[F[_]: Sync]: Pipe[F, String, String] =
|
||||
override def part2[F[_]: Sync]: Pipe[F, String, String] =
|
||||
parts[F](3)
|
||||
|
||||
def parts[F[_]: Sync](nums: Int): Pipe[F, String, String] =
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package tf.bug.aoc.y2020
|
||||
|
||||
import cats.effect._
|
||||
import cats.parse.{Parser => P, Parser1, Numbers}
|
||||
import cats.syntax.all._
|
||||
import fs2._
|
||||
import tf.bug.aoc.Day
|
||||
|
||||
object Day2 extends Day:
|
||||
|
||||
case class Policy(min: Int, max: Int, letter: Char)
|
||||
case class Entry(policy: Policy, password: String)
|
||||
|
||||
val parsePolicy: Parser1[Policy] =
|
||||
(Numbers.nonNegativeIntString, P.char('-'), Numbers.nonNegativeIntString, P.char(' '), P.anyChar).mapN {
|
||||
case (min, (), max, (), letter) =>
|
||||
Policy(min.toInt, max.toInt, letter)
|
||||
}
|
||||
|
||||
val parseEntry: Parser1[Entry] =
|
||||
(parsePolicy, P.string1(": "), P.until1(P.end)).mapN {
|
||||
case (policy, (), password) =>
|
||||
Entry(policy, password)
|
||||
}
|
||||
|
||||
override def part1[F[_]: Sync]: 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] =
|
||||
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
|
||||
(a || b) && !(a && b)
|
||||
}
|
||||
|
||||
def parts[F[_]: Sync](validation: Entry => Boolean): Pipe[F, String, String] =
|
||||
(lines: Stream[F, String]) => {
|
||||
lines.map(parseEntry.parseAll)
|
||||
.collect {
|
||||
case Right(entry) => entry
|
||||
}
|
||||
.foldMap(ent => if(validation(ent)) 1 else 0)
|
||||
.map(_.show)
|
||||
}
|
|
@ -5,4 +5,5 @@ import tf.bug.aoc.{Day, Year}
|
|||
object y2020 extends Year:
|
||||
override def days: Map[Int, Day] = Map(
|
||||
1 -> Day1,
|
||||
2 -> Day2,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue