From 28d60b0bb741d3ad75d4c5b2dd66976c27586b98 Mon Sep 17 00:00:00 2001 From: Juris Date: Thu, 19 Dec 2024 07:16:08 +0200 Subject: [PATCH] 2024-19 Scala 2 --- .../jurisk/adventofcode/y2024/Advent19.scala | 44 ++++++++++++++----- .../adventofcode/y2024/Advent19Spec.scala | 4 +- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent19.scala b/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent19.scala index 373a088d..c2cd8c1d 100644 --- a/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent19.scala +++ b/scala2/src/main/scala/jurisk/adventofcode/y2024/Advent19.scala @@ -1,6 +1,7 @@ package jurisk.adventofcode.y2024 import jurisk.utils.FileInput._ +import jurisk.utils.Memoize import jurisk.utils.Parsing.StringOps object Advent19 { @@ -8,7 +9,7 @@ object Advent19 { stripes: List[String], towels: List[String], ) - type N = Int + type N = Long def parse(input: String): Input = { val (stripes, towels) = input.split("\n\n").toList match { @@ -18,22 +19,41 @@ object Advent19 { Input(stripes, towels) } - private def isValid(towel: String, stripes: List[String]): Boolean = { - if (towel.isEmpty) true - else { - stripes.exists { stripe => -// println(s"Towel $towel, Stripe $stripe, Starts: ${towel.startsWith(stripe)}") - towel.startsWith(stripe) && isValid(towel.drop(stripe.length), stripes) + def part1(data: Input): N = { + def ways(towel: String, stripes: List[String]): N = { + if (towel.isEmpty) 1L + else { + stripes.map { stripe => + if (towel.startsWith(stripe)) { + ways(towel.drop(stripe.length), stripes) + } else { + 0L + } + }.sum } } - } - def part1(data: Input): N = { - data.towels.count(towel => isValid(towel, data.stripes)) + data.towels.count(towel => ways(towel, data.stripes) > 0) } - def part2(data: Input): N = - 0 + def part2(data: Input): N = { + lazy val waysMemoized = Memoize.memoize1(ways) + + def ways(towel: String): N = { + if (towel.isEmpty) 1L + else { + data.stripes.map { stripe => + if (towel.startsWith(stripe)) { + waysMemoized(towel.drop(stripe.length)) + } else { + 0L + } + }.sum + } + } + + data.towels.map(towel => waysMemoized(towel)).sum + } def parseFile(fileName: String): Input = parse(readFileText(fileName)) diff --git a/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent19Spec.scala b/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent19Spec.scala index 4e730ac9..7aed7b14 100644 --- a/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent19Spec.scala +++ b/scala2/src/test/scala/jurisk/adventofcode/y2024/Advent19Spec.scala @@ -20,11 +20,11 @@ class Advent19Spec extends AnyFreeSpec { "part 2" - { "test" in { - part2(testData) shouldEqual 0 + part2(testData) shouldEqual 16 } "real" in { - part2(realData) shouldEqual 0 + part2(realData) shouldEqual 1100663950563322L } } }