Skip to content

Instantly share code, notes, and snippets.

@CJSmith-0141
Created December 11, 2023 01:01
Show Gist options
  • Save CJSmith-0141/8095b7a0d1cb8aff4be3f2082df4b1d4 to your computer and use it in GitHub Desktop.
Save CJSmith-0141/8095b7a0d1cb8aff4be3f2082df4b1d4 to your computer and use it in GitHub Desktop.
AoC 2023 Day 6
package net.tazato
import cats.*
import cats.data.NonEmptyList
import cats.effect.*
import cats.parse.Parser as P
import cats.parse.Numbers.digits
import cats.parse.Rfc5234.lf
import cats.parse.Rfc5234.wsp
import cats.syntax.all.*
object Day6 extends IOApp.Simple {
val input = io.Source.fromResource("day6.txt").mkString
def part1F(i: String) = IO.delay {
Parse.all.parseAll(i) match
case Left(value) =>
IO.raiseError(new Throwable(s"parse error:\n${value.show}"))
case Right(value: NonEmptyList[(Int, Int)]) =>
val inputs = value.map(pair => 0 to pair._1)
val poly = value.map[Int => Int] { case (time, record) =>
(hold: Int) => (time * hold) - (hold * hold) - record
}
val result = inputs
.zip(poly)
.map[Int] { case (input, poly) =>
val r = input.toList.map(poly).count(_ > 0)
r
}
.foldLeft(1)(_ * _)
result
}
def part2F(i: String) = IO.delay {
Parse.allPart2.parseAll(i) match
case Left(value) =>
IO.raiseError(new Throwable(s"parse error:\n${value.show}"))
case Right(value) =>
val (allowed, record) = value
val inputs = (0L to allowed).toList
val poly = (hold: Long) => (allowed * hold) - (hold * hold) - record
val result = inputs.map(poly).count(_ > 0)
result
}
override def run: IO[Unit] =
part2F(input).flatMap(r => IO.println(s"part2: $r"))
object Parse {
val times =
P.string("Time:") *> digits.map(_.toInt).surroundedBy(wsp.rep0).rep
val records =
P.string("Distance:") *> digits.map(_.toInt).surroundedBy(wsp.rep0).rep
val all = (times, lf.void, records).mapN((t, _, r) => t.zip(r))
val allPart2 = (times, lf.void, records).mapN { (t, _, r) =>
val time = t.foldLeft("")((acc, v) => acc ++ v.toString).toLong
val record = r.foldLeft("")((acc, v) => acc ++ v.toString).toLong
(time, record)
}
}
}
package net.tazato
import cats.syntax.all.*
import weaver.*
object Day6Suite extends SimpleIOSuite {
val example =
"""Time: 7 15 30
|Distance: 9 40 200""".stripMargin
pureTest("parse example") {
Day6.Parse.all.parseAll(example) match
case Left(value) => failure(s"failed to parse\n${value.show}")
case Right(value) => success
}
test("example works part 1") {
Day6.part1F(example) map { result =>
expect(result == 288)
}
}
pureTest("example works part 2") {
Day6.Parse.allPart2.parseAll(example) match
case Left(value) => failure(s"failed to parse\n${value.show}")
case Right(value) => expect.same(value, (71530, 940200))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment