Skip to content

Commit

Permalink
Day 3 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
horothesun committed Dec 3, 2024
1 parent 24afbd4 commit 436d9c1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/main/scala/Day03.scala
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)
26 changes: 26 additions & 0 deletions src/test/scala/Day03Suite.scala
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))")
Loading

0 comments on commit 436d9c1

Please sign in to comment.