+ let (ccE, startPosition) = buildCaveComplex text
+ -- print ccE
+ -- print $ S.size $ edgeC $ _caveE ccE
+ -- print $ S.size $ _cave $ contractCave ccE [startPosition]
+ -- putStrLn $ showContracted $ contractCave ccE [startPosition]
+ -- let (re, ce) = startPosition
+ -- let startPositions = [(re - 1, ce - 1), (re - 1, ce + 1), (re + 1 , ce - 1), (re + 1, ce + 1)]
+ -- let cavern0 = ccE ^. caveE
+ -- let cavern = cavern0 `S.difference` [(re, ce), (re + 1, ce), (re - 1, ce), (re, ce + 1), (re, ce - 1)]
+ -- let caveComplex = ccE & caveE .~ cavern
+ -- let cc = contractCave caveComplex startPositions
+ -- putStrLn $ showContracted cc
+ print $ part1 ccE startPosition
+ print $ part2 ccE startPosition
+
+-- edgeC ec = S.foldl' ecAdd S.empty ec
+-- where ecAdd es n = S.union (eds n) es
+-- eds n = S.map (\m -> S.fromList [n, m]) $ nbrs n
+-- nbrs n = S.intersection ec $ possibleNeighbours n
+
+
+part1 :: ExpandedCaveComplex -> Position -> Int
+part1 cavern startPosition = maybe 0 _cost result
+ where cc = contractCave cavern [startPosition]
+ explorer = emptyExplorer ['0']
+ result = runReader (searchCave explorer) cc
+
+part2 :: ExpandedCaveComplex -> Position -> Int
+part2 caveComplex0 (re, ce) = maybe 0 _cost result
+ where
+ startPositions = [(re - 1, ce - 1), (re - 1, ce + 1), (re + 1 , ce - 1), (re + 1, ce + 1)]
+ cavern0 = caveComplex0 ^. caveE
+ cavern = cavern0 `S.difference` [(re, ce), (re + 1, ce), (re - 1, ce), (re, ce + 1), (re, ce - 1)]
+ caveComplex = caveComplex0 {_caveE = cavern}
+ cc = contractCave caveComplex startPositions
+ explorer = emptyExplorer $ S.fromList "0123"
+ result = runReader (searchCave explorer) cc
+
+
+buildCaveComplex :: String -> (ExpandedCaveComplex, Position)
+buildCaveComplex text = (ccE, startPosition)
+ where (ccE, startPosition) = foldl' buildCaveRow (cc0, (0, 0)) $ zip [0..] rows
+ cc0 = ExpandedCaveComplex {_caveE = S.empty, _keysE = M.empty, _doors = M.empty}
+ rows = lines text