day12: use hashset instead of list traversal

This commit is contained in:
Quinten Kock 2021-12-13 00:58:33 +01:00
parent 294bc0e55d
commit a8404b5872
1 changed files with 13 additions and 10 deletions

View File

@ -1,4 +1,5 @@
module Day12 where
import Data.HashSet (HashSet, member, insert, fromList)
import Data.Map ( Map, fromList, unionWith, empty, (!) )
import Data.List.Split (splitOn)
import qualified Data.Char
@ -15,16 +16,18 @@ addPath (from,to) = unionWith (++) (Data.Map.fromList [(from,[to]), (to,[from])]
isUpper :: String -> Bool
isUpper = Data.Char.isUpper . head
pathFinder :: System -> [String] -> [[String]]
pathFinder sys p@("end":xs) = [p]
pathFinder sys p@(x:xs) = concatMap (\next -> pathFinder sys (next:p)) elig
where elig = filter (\cave -> isUpper cave || cave `notElem` p) (sys ! x)
pathFinder :: System -> [String] -> HashSet String -> [[String]]
pathFinder _ [] _ = error "no starting point!"
pathFinder sys p@("end":xs) _ = [p]
pathFinder sys p@(x:xs) visited = concatMap (\next -> pathFinder sys (next:p) (next `insert` visited)) elig
where elig = filter (\cave -> isUpper cave || not (cave `member` visited)) (sys ! x)
pathFinder2 :: System -> [String] -> [[String]]
pathFinder2 sys p@("end":xs) = [p]
pathFinder2 sys p@(x:xs) = concatMap (\next -> f next sys (next:p)) elig
pathFinder2 :: System -> [String] -> HashSet String -> [[String]]
pathFinder2 _ [] _ = error "no starting point!"
pathFinder2 sys p@("end":xs) _ = [p]
pathFinder2 sys p@(x:xs) visited = concatMap (\next -> f next sys (next:p) (next `insert` visited)) elig
where
f cave = if isUpper cave || cave `notElem` p then pathFinder2 else pathFinder
f cave = if isUpper cave || not (cave `member` visited) then pathFinder2 else pathFinder
elig = filter (/= "start") (sys ! x)
main :: IO ()
@ -33,9 +36,9 @@ main = do
let system = foldr addPath Data.Map.empty input
putStrLn "part 1: "
let paths = map reverse $ pathFinder system ["start"]
let paths = map reverse $ pathFinder system ["start"] (Data.HashSet.fromList ["start"])
print $ length paths
putStrLn "part 2: "
let paths = map reverse $ pathFinder2 system ["start"]
let paths = map reverse $ pathFinder2 system ["start"] (Data.HashSet.fromList ["start"])
print $ length paths