-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
24afbd4
commit 436d9c1
Showing
3 changed files
with
57 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import cats.data.NonEmptyList | ||
import cats.parse.{Parser, Parser0} | ||
import cats.parse.Numbers.nonNegativeIntString | ||
import cats.parse.Parser.{char, end, string, until, until0, Error} | ||
import cats.syntax.all.* | ||
|
||
object Day03: | ||
|
||
case class Mul(x: Int, y: Int): | ||
def eval: Int = x * y | ||
|
||
object Mul: | ||
def parser: Parser[Mul] = | ||
val natLt1k = nonNegativeIntString.collect { case s if 1 <= s.length && s.length <= 3 => s.toInt } | ||
val natLt1kPair = ( | ||
char('(') *> natLt1k.repSep(sep = char(',')) <* char(')') | ||
).collect { case NonEmptyList(x, y :: Nil) => (x, y) } | ||
string("mul") *> natLt1kPair.map(Mul.apply.tupled) | ||
|
||
val mulsOnlyParser: Parser0[List[Mul]] = | ||
val mulRep = Mul.parser.backtrack.rep.map(_.toList) | ||
until0(Mul.parser) *> mulRep.repSep0(sep = until(Mul.parser)).map(_.flatten) <* until0(end) | ||
|
||
def evalMulsOnly(inputs: List[String]): Either[Error, Int] = | ||
inputs.traverse(s => mulsOnlyParser.parseAll(s).map(_.foldMap(_.eval))).map(_.sum) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import Day03.* | ||
import Day03Suite.* | ||
import munit.ScalaCheckSuite | ||
|
||
class Day03Suite extends ScalaCheckSuite: | ||
|
||
test("parsing \"mul(42,1)\""): | ||
assertEquals(Mul.parser.parse("mul(42,1)"), Right(("", Mul(42, 1)))) | ||
|
||
test("parsing Muls only from small input"): | ||
assertEquals( | ||
mulsOnlyParser.parseAll(smallInput.head), | ||
Right(List(Mul(2, 4), Mul(5, 5), Mul(11, 8), Mul(8, 5))) | ||
) | ||
|
||
test("eval Muls only from small input returns 161"): | ||
assertEquals(evalMulsOnly(smallInput), Right(161)) | ||
|
||
test("eval Muls only from big input returns 184_511_516"): | ||
assertEquals(evalMulsOnly(bigInput), Right(184_511_516)) | ||
|
||
object Day03Suite: | ||
|
||
val bigInput: List[String] = getLinesFromFile("src/test/scala/day03_input.txt") | ||
|
||
val smallInput: List[String] = List("xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))") |
Oops, something went wrong.