@@ -208,17 +208,19 @@ def shortestProgramLength(robots: Int, goal: String): Int =
208
208
209
209
throw RuntimeException (" No shortest program found" )
210
210
211
- def solve (robots : Int , goals : List [String ], func : (Int , String ) => Int ): Int =
211
+ def solve (robots : Int , goals : List [String ], func : (Int , String ) => Long ): Long =
212
212
goals.map { goal =>
213
213
val shortest = func(robots, goal)
214
- shortest * goal.dropRight(1 ).toInt
214
+ shortest * goal.dropRight(1 ).toLong
215
215
}.sum
216
216
217
- // Algorithm/approach inspired by https://www.reddit.com/r/adventofcode/comments/1hj2odw/comment/m36j01x
217
+ // Algorithm/approach is effectively a Scala port of
218
+ // https://www.reddit.com/r/adventofcode/comments/1hj2odw/comment/m36j01x For
219
+ // some reason my Dijkstra-based shortest-path constructions didn't yield the
220
+ // specific/right ordering, so I eventually just ended up using the hardcoded
221
+ // map too. Most of the experiments can be found in earlier commits.
218
222
219
- val SHORTEST_PATHS = PadType .Num .shortestPaths ++ PadType .Dir .shortestPaths
220
-
221
- val SHORTEST_PATHS_2 = Map (
223
+ val SHORTEST_PATHS = Map (
222
224
(('A' , '0' ), " <A" ),
223
225
(('0' , 'A' ), " >A" ),
224
226
(('A' , '1' ), " ^<<A" ),
@@ -351,19 +353,26 @@ val SHORTEST_PATHS_2 = Map(
351
353
(('A' , '>' ), " vA" ),
352
354
)
353
355
354
- def shortestProgramLengthClever (robots : Int , goal : String ): Int =
355
- // TODO: Memoize
356
- if robots < 0 then
357
- goal.length
356
+ val memo = mutable.Map [(Int , String ), Long ]()
357
+
358
+ def shortestProgramLengthClever (robots : Int , goal : String ): Long =
359
+ val key = (robots, goal)
360
+ if memo.contains(key) then
361
+ return memo(key)
362
+
363
+ val result = if robots < 0 then
364
+ goal.length.toLong
358
365
else
359
366
var current = 'A'
360
- var length = 0
367
+ var length = 0L
361
368
for next <- goal do
362
369
length += moveCount(robots, current, next)
363
370
current = next
364
371
length
372
+ memo(key) = result
373
+ result
365
374
366
- def moveCount (robots : Int , current : Char , next : Char ): Int =
375
+ def moveCount (robots : Int , current : Char , next : Char ): Long =
367
376
if current == next then
368
377
1
369
378
else
@@ -374,12 +383,15 @@ def moveCount(robots: Int, current: Char, next: Char): Int =
374
383
// println(s"Part 1: ${solve(2, goals)}")
375
384
// println(s"Part 2: ${solve(25, goals)}")
376
385
377
- for (k, p) <- SHORTEST_PATHS .toList.sorted do
378
- if k._1 != k._2 && p != SHORTEST_PATHS_2 (k) then
379
- println(s " ( \" $p\" , \" ${SHORTEST_PATHS_2 (k)}\" ) " )
386
+ // for (k, p) <- SHORTEST_PATHS.toList.sorted do
387
+ // if k._1 != k._2 && p != SHORTEST_PATHS_2(k) then
388
+ // println(s"(\"$p\", \"${SHORTEST_PATHS_2(k)}\")")
389
+
390
+ println(s " Part 1: ${solve(2 , goals, shortestProgramLengthClever)}" )
391
+ println(s " Part 2: ${solve(25 , goals, shortestProgramLengthClever)}" )
380
392
381
- for i <- (0 to 3 ) do
382
- println(s " ${solve(i, goals, { (r, g) => shortestProgram(r, g).length })} vs ${solve(i, goals, shortestProgramLength)} vs ${solve(i, goals, shortestProgramLengthClever)}" )
393
+ // for i <- (0 to 3) do
394
+ // println(s"${solve(i, goals, { (r, g) => shortestProgram(r, g).length })} vs ${solve(i, goals, shortestProgramLength)} vs ${solve(i, goals, shortestProgramLengthClever)}")
383
395
384
396
// for c <- ('0' to '5') do
385
397
// println(s"$c -> ${(0 to 3).map { i => shortestProgram(makeState(i), s"$c").length }}")
0 commit comments