Skip to content

Commit 1f8232d

Browse files
committed
Add permutation solution to 2025 day 11
1 parent 81d234b commit 1f8232d

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/main/scala/eu/sim642/adventofcode2025/Day11.scala

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package eu.sim642.adventofcode2025
22

3+
import scala.annotation.tailrec
34
import scala.collection.mutable
45

56
object Day11 {
@@ -58,7 +59,45 @@ object Day11 {
5859
override object Part2 extends ViaMapPartSolution with Part2Devices
5960
}
6061

61-
// TODO: path count product solution
62+
/**
63+
* Solution, which tries all permutations of vias and counts each one by multiplying adjacent steps.
64+
*/
65+
object PermutationSolution extends Solution {
66+
trait PermutationPartSolution extends PartSolution {
67+
def countPathsTo(devices: Devices)(to: Device): Device => Long = {
68+
val memo = mutable.Map.empty[Device, Long]
69+
70+
def helper(device: Device): Long = {
71+
memo.getOrElseUpdate(device, {
72+
if (device == to)
73+
1
74+
else
75+
devices.getOrElse(device, Set.empty).map(helper).sum // need getOrElse for "out" when from is different, but reaches "out"
76+
})
77+
}
78+
79+
helper
80+
}
81+
82+
override def countPaths(devices: Devices): Long = {
83+
val memo = mutable.Map.empty[Device, Device => Long]
84+
85+
def countPathsFromTo(from: Device, to: Device): Long = // memoize by to, because same to will be reused
86+
memo.getOrElseUpdate(to, countPathsTo(devices)(to))(from)
87+
88+
@tailrec
89+
def helper(prevDevice: Device, acc: Long, via: List[Device]): Long = via match {
90+
case Nil => acc * countPathsFromTo(prevDevice, to)
91+
case device :: newVia => helper(device, acc * countPathsFromTo(prevDevice, device), newVia) // TODO: optimize: stop when countPathsFromTo is zero
92+
}
93+
94+
via.toList.permutations.map(helper(from, 1L, _)).sum // TODO: optimize: only one can be non-zero, stop on first
95+
}
96+
}
97+
98+
override object Part1 extends PermutationPartSolution with Part1Devices
99+
override object Part2 extends PermutationPartSolution with Part2Devices
100+
}
62101

63102
def parseDevice(s: String): (Device, Seq[Device]) = s match {
64103
case s"$key: $values" => key -> values.split(" ").toSeq

src/test/scala/eu/sim642/adventofcode2025/Day11Test.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import org.scalatest.funsuite.AnyFunSuite
77

88
class Day11Test extends Suites(
99
new ViaMapSolutionTest,
10+
new PermutationSolutionTest,
1011
)
1112

1213
object Day11Test {
@@ -57,4 +58,6 @@ object Day11Test {
5758
}
5859

5960
class ViaMapSolutionTest extends SolutionTest(ViaMapSolution)
61+
62+
class PermutationSolutionTest extends SolutionTest(PermutationSolution)
6063
}

0 commit comments

Comments
 (0)