From c05570fc4abcfd03f8d5eddb3915725ab50a4474 Mon Sep 17 00:00:00 2001 From: Taras Mychaskiw Date: Thu, 19 Dec 2024 12:56:32 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9A=97=EF=B8=8F=20fiddling=20with=20parsing?= =?UTF-8?q?=20util?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/scala/org/lemon/advent/lib/parse.scala | 16 ++++++++++++---- .../scala/org/lemon/advent/year2024/Day18.scala | 8 +++++--- .../scala/org/lemon/advent/year2024/Day19.scala | 6 ++++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/main/scala/org/lemon/advent/lib/parse.scala b/src/main/scala/org/lemon/advent/lib/parse.scala index e80f94d..6064652 100644 --- a/src/main/scala/org/lemon/advent/lib/parse.scala +++ b/src/main/scala/org/lemon/advent/lib/parse.scala @@ -1,20 +1,28 @@ package org.lemon.advent.lib +import scala.math.BigInt + object Chunk: def unapplySeq(str: String): Option[Seq[String]] = Some(str.split("\n\n").toSeq) object Num: def unapply[T: Numeric](s: String): Option[T] = summon[Numeric[T]].parseString(s) +// givens for delimiter-separated values to be generic +given (String => Option[String]) = Some(_) +given (String => Option[Int]) = Int.unapply +given (String => Option[Long]) = Long.unapply +given (String => Option[BigInt]) = BigInt.unapply + object Csv: private val delimeter = "," - def unapplySeq[T: Numeric](str: String): Option[Seq[T]] = Some(splitParse(str, delimeter).flatMap(Num.unapply[T])) - def unapplySeq(str: String): Option[Seq[String]] = Some(splitParse(str, delimeter)) + def unapplySeq[T](str: String)(using unapply: String => Option[T]): Option[Seq[T]] = + Some(splitParse(str, delimeter).flatMap(unapply)) object Wsv: private val delimeter = "\\s+" - def unapplySeq[T: Numeric](str: String): Option[Seq[T]] = Some(splitParse(str, delimeter).flatMap(Num.unapply[T])) - def unapplySeq(str: String): Option[Seq[String]] = Some(splitParse(str, delimeter)) + def unapplySeq[T](str: String)(using unapply: String => Option[T]): Option[Seq[T]] = + Some(splitParse(str, delimeter).flatMap(unapply)) private def splitParse(str: String, delimeter: String): Seq[String] = str.split(delimeter).map(_.trim).toSeq diff --git a/src/main/scala/org/lemon/advent/year2024/Day18.scala b/src/main/scala/org/lemon/advent/year2024/Day18.scala index 83c7c43..efc6f65 100644 --- a/src/main/scala/org/lemon/advent/year2024/Day18.scala +++ b/src/main/scala/org/lemon/advent/year2024/Day18.scala @@ -6,9 +6,11 @@ import org.lemon.advent.lib.graph._ private object Day18: - def parse(input: String) = input.linesIterator.map(_ match - case s"${Csv[Int](x, y)}" => Coord(x, y) - ).toSeq + def parse(input: String) = + import org.lemon.advent.lib.given + input.linesIterator.map(_ match + case s"${Csv[Int](x, y)}" => Coord(x, y) + ).toSeq def adjacency(area: Area, corrupt: Set[Coord])(coord: Coord): Seq[Coord] = coord.adjacent.filterNot(corrupt).filter(area.contains) diff --git a/src/main/scala/org/lemon/advent/year2024/Day19.scala b/src/main/scala/org/lemon/advent/year2024/Day19.scala index add417f..0e0f5cb 100644 --- a/src/main/scala/org/lemon/advent/year2024/Day19.scala +++ b/src/main/scala/org/lemon/advent/year2024/Day19.scala @@ -6,8 +6,10 @@ import scala.collection.mutable private object Day19: - def parse(input: String) = input match - case Chunk(towels, targets) => (towels.split(",").map(_.trim).toSeq, targets.linesIterator.toSeq) + def parse(input: String) = + import org.lemon.advent.lib.given + input match + case Chunk(Csv[String](towels @ _*), Wsv[String](targets @ _*)) => (towels, targets) def countLayouts(towels: Seq[String], target: String) = val memo = mutable.Map("" -> 1L)