Skip to content

Instantly share code, notes, and snippets.

@erdeszt
Last active December 6, 2024 16:05
Show Gist options
  • Save erdeszt/4248c4c0e84002b34a75203205eac2e9 to your computer and use it in GitHub Desktop.
Save erdeszt/4248c4c0e84002b34a75203205eac2e9 to your computer and use it in GitHub Desktop.
Advent of code "framework"
import scala.util.Using
trait Solver[Day <: Int: ValueOf, Part <: Int: ValueOf]:
/** Solves the `Part` of the solution for the `Day`
*
* @param input
* The lines of the input file
* @return
* The solution
*/
def solve(input: Vector[String]): Int
object Solver:
def solve[Day <: Int: ValueOf, Part <: Int: ValueOf](using
solver: Solver[Day, Part],
): Unit =
val input = Using(
scala.io.Source.fromResource(
s"inputs/day${valueOf[Day]}.txt",
),
)(_.getLines().toVector).get
val solution = solver.solve(input)
println(
s"Solution to Day ${valueOf[Day]}, part ${valueOf[Part]}: ${solution}",
)
@main
def main(): Unit =
Solver.solve[1, 1]
given day1Part1Solution: Solver[1, 1] = new Solver[1, 1]:
override def solve(input: Vector[String]): Int =
// no spoilers :)
-1
given day1Part2Solution: Solver[1, 2] = new Solver[1, 2]:
override def solve(input: Vector[String]): Int =
// no spoilers :)
-1
import org.scalatest.flatspec.AnyFlatSpec
trait ExampleValidator[Day <: Int: ValueOf](
part1Solution: Int,
part2Solution: Int,
)(examples: Vector[String] | (Vector[String], Vector[String]))(using
Solver[Day, 1],
Solver[Day, 2],
) extends AnyFlatSpec:
private type Selector = ((Vector[String], Vector[String])) => Vector[String]
private def validateExample[Part <: Int: ValueOf](using
Solver[Day, Part],
): Unit = {
s"Day ${valueOf[Day]}, Part ${valueOf[Part]}" should "produce the correct result for the example" in {
val (selector, expectedResult): (Selector, Int) =
valueOf[Part] match
case 1 => ((_._1): Selector, part1Solution)
case 2 => ((_._2): Selector, part2Solution)
case _ => throw Exception(s"Invalid part number: ${valueOf[Part]}")
val solution = summon[Solver[Day, Part]].solve(
examples match
case tuple: (Vector[_], Vector[_]) => selector(tuple)
case vector: Vector[_] => vector,
)
assert(solution == expectedResult)
}
}
validateExample[1]
validateExample[2]
class Day1Test
extends ExampleValidator[1](11, 31)(
Vector(
"3 4",
"4 3",
"2 5",
"1 3",
"3 9",
"3 3",
),
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment