diff --git a/projects/aoc/src/year2021/Solutions2021.kiss b/projects/aoc/src/year2021/Solutions2021.kiss index 8eafd097..e59e796b 100644 --- a/projects/aoc/src/year2021/Solutions2021.kiss +++ b/projects/aoc/src/year2021/Solutions2021.kiss @@ -69,7 +69,9 @@ (day 12 (load "day12.kiss") (assert (= 10 .length (allPaths "start" "end" "src/year2021/inputs/day12-example.txt"))) - (assert (= 3421 .length (allPaths "start" "end" "src/year2021/inputs/day12.txt")))) + (assert (= 36 .length (allPaths "start" "end" "src/year2021/inputs/day12-example.txt" true))) + (assert (= 3421 .length (allPaths "start" "end" "src/year2021/inputs/day12.txt"))) + (assert (= 84870 .length (allPaths "start" "end" "src/year2021/inputs/day12.txt" true)))) (dayTodo 13) (dayTodo 14) (dayTodo 15) diff --git a/projects/aoc/src/year2021/day12.kiss b/projects/aoc/src/year2021/day12.kiss index 89eb0a6d..154de868 100644 --- a/projects/aoc/src/year2021/day12.kiss +++ b/projects/aoc/src/year2021/day12.kiss @@ -11,27 +11,38 @@ (link to from m))) m)) -(function :Array> allPaths [start end file] +(function :Array> allPaths [start end file &opt part2] (let [pMap (pathsMap file) - :Array> paths [] - :Array> pathsVisited []] - (paths.push [start]) + &mut :Array> paths [[start]] + &mut :Array> pathsVisited [] + &mut :Array pathsDoubleVisited [false] + :Array> finishedPaths []] (let [pathVisited (new Map)] (dictSet pathVisited start true) (pathsVisited.push pathVisited)) - (until (apply = (concat [end] (for path paths (last path)))) - (doFor idx (reversed (collect (range paths.length))) - (let [path (nth paths idx) - pathVisited (nth pathsVisited idx) - position (last path)] - (when (= end position) (continue)) - (paths.splice idx 1) - (pathsVisited.splice idx 1) - (doFor nextPosition (dictGet pMap position) - (unless (dictGet pathVisited nextPosition) - (paths.insert idx (concat (path.copy) [nextPosition])) - (let [nextPathVisited (pathVisited.copy)] - (when (nextPosition.isLowerCase) - (dictSet nextPathVisited nextPosition true)) - (pathsVisited.insert idx nextPathVisited))))))) - paths)) \ No newline at end of file + (while paths + (let [:Array> nextPaths [] + :Array> nextPathsVisited [] + :kiss.List nextPathsDoubleVisited []] + (while paths + (let [path (paths.pop) + pathVisited (pathsVisited.pop) + pathDoubleVisited (pathsDoubleVisited.pop) + position (last path)] + (when (= end position) + (finishedPaths.push path) + (continue)) + (doFor nextPosition (dictGet pMap position) + (let [alreadyVisited (dictGet pathVisited nextPosition)] + (when (or !alreadyVisited (and part2 !pathDoubleVisited !(= nextPosition start))) + (nextPathsDoubleVisited.push pathDoubleVisited) + (when alreadyVisited (setNth nextPathsDoubleVisited -1 alreadyVisited)) + (nextPaths.push (concat (path.copy) [nextPosition])) + (let [nextPathVisited (pathVisited.copy)] + (when (nextPosition.isLowerCase) + (dictSet nextPathVisited nextPosition true)) + (nextPathsVisited.push nextPathVisited))))))) + (set paths nextPaths) + (set pathsVisited nextPathsVisited) + (set pathsDoubleVisited nextPathsDoubleVisited))) + finishedPaths)) \ No newline at end of file