@@ -64,37 +64,48 @@ object Day11 {
6464 * Others are useless for passing all the vias.
6565 */
6666 object ViaPairSolution extends Solution {
67+
68+ case class ViaPair (via : Set [Device ], count : Long ) {
69+ infix def combine (that : ViaPair ): ViaPair = {
70+ if (via == that.via)
71+ ViaPair (via, count + that.count)
72+ else if (via subsetOf that.via)
73+ that
74+ else if (that.via subsetOf via)
75+ this
76+ else
77+ throw new IllegalArgumentException (" incomparable via pairs" ) // doesn't happen on DAG
78+ }
79+
80+ def unionVia (thatVia : Set [Device ]): ViaPair =
81+ copy(via = via union thatVia)
82+ }
83+
84+ object ViaPair {
85+ val empty = ViaPair (Set .empty, 0 )
86+ }
87+
6788 trait ViaPairPartSolution extends PartSolution {
6889 override def countPaths (devices : Devices ): Long = {
69- val memo = mutable.Map .empty[Device , ( Set [ Device ], Long ) ]
90+ val memo = mutable.Map .empty[Device , ViaPair ]
7091
71- def helper (device : Device ): ( Set [ Device ], Long ) = {
92+ def helper (device : Device ): ViaPair = {
7293 memo.getOrElseUpdate(device, {
7394 val deviceVia = via.intersect(Set (device))
7495 if (device == to)
75- deviceVia -> 1
76- else {
77- val (a, b) = devices(device).map(helper).foldLeft(Set .empty[Device ] -> 0L )({ case (a@ (accVia, acc), n@ (newVia, newCount)) =>
78- if (accVia == newVia)
79- accVia -> (acc + newCount)
80- else if (accVia subsetOf newVia)
81- n
82- else if (newVia subsetOf accVia)
83- a
84- else
85- throw new IllegalStateException (" " )
86- })
87- a.union(deviceVia) -> b
88- }
96+ ViaPair (deviceVia, 1 )
97+ else
98+ devices(device).map(helper).foldLeft(ViaPair .empty)(_ combine _).unionVia(deviceVia)
8999 })
90100 }
91101
92- helper(from)._2
102+ val viaPair = helper(from)
103+ assert(viaPair.via == via)
104+ viaPair.count
93105 }
94106 }
95107
96108 override object Part1 extends ViaPairPartSolution with Part1Devices
97-
98109 override object Part2 extends ViaPairPartSolution with Part2Devices
99110 }
100111
0 commit comments