Done day 12 part 1
authorNeil Smith <neil.git@njae.me.uk>
Mon, 13 Dec 2021 09:56:56 +0000 (09:56 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Mon, 13 Dec 2021 09:56:56 +0000 (09:56 +0000)
advent-of-code21.cabal
advent12/Main.hs [new file with mode: 0644]
data/advent12.txt [new file with mode: 0644]
data/advent12a.txt [new file with mode: 0644]
data/advent12c.txt [new file with mode: 0644]

index 12cd8ab73022406d094f5d2bf543f949d105cfbd..ac846cfaa2087d895a5990337933f7216ab43c47 100644 (file)
@@ -139,3 +139,8 @@ executable advent11
   import: common-extensions, build-directives
   main-is: advent11/Main.hs
   build-depends: array, containers, linear
+
+executable advent12
+  import: common-extensions, build-directives
+  main-is: advent12/Main.hs
+  build-depends: text, attoparsec, containers
diff --git a/advent12/Main.hs b/advent12/Main.hs
new file mode 100644 (file)
index 0000000..59d73a3
--- /dev/null
@@ -0,0 +1,82 @@
+-- Writeup at https://work.njae.me.uk/2021/12/09/advent-of-code-2021-day-8/
+
+
+import Data.Text ()
+import qualified Data.Text.IO as TIO
+
+import Data.Attoparsec.Text
+-- import Control.Applicative
+
+import Data.Tuple
+-- import Data.List
+import Data.Char
+import qualified Data.Map.Strict as M
+import Data.Map.Strict ((!))
+import qualified Data.Set as S
+import Data.Set ((\\))
+
+data Path = Path String [String] (S.Set String)
+  deriving (Eq, Ord, Show)
+
+type PathSet = S.Set Path
+type Graph = M.Map String (S.Set String)
+
+
+
+main :: IO ()
+main = 
+  do  text <- TIO.readFile "data/advent12.txt"
+      let edges = successfulParse text
+      print edges
+      let graph = mkGraph edges
+      print graph
+      print $ part1 graph
+      -- print $ part1 displays
+      -- print $ part2 displays
+
+mkGraph :: [(String, String)] -> Graph
+mkGraph edges = foldr mkEdge pass1 $ map swap edges
+  where pass1 = foldr mkEdge M.empty edges
+        mkEdge (here, there) g = M.insertWith (S.union) here (S.singleton there) g
+
+part1 graph = S.size $ allPaths graph (S.singleton (Path "start" [] S.empty)) S.empty
+
+allPaths :: Graph -> PathSet -> PathSet -> PathSet
+allPaths graph agenda results
+  | S.null agenda = results
+  | otherwise = allPaths graph agenda'' results'
+  where (current, agenda') = S.deleteFindMin agenda
+        newPaths = extendPath graph current
+        agenda'' = S.union agenda' newPaths
+        results' = S.union results $ recordResult current
+
+extendPath :: Graph -> Path -> PathSet
+extendPath graph (Path current trail visited) 
+  | current == "end" = S.empty
+  | otherwise = S.map newPath visitable
+  where neighbours = graph ! current
+        visited' = if isSmall current then S.insert current visited else visited
+        trail' = (current:trail)
+        visitable = neighbours \\ visited
+        newPath next = Path next trail' visited'
+
+recordResult :: Path -> PathSet
+recordResult path@(Path current _trail _visited)
+  | current == "end" = S.singleton path -- (Path current trail visited)
+  | otherwise = S.empty
+
+
+isSmall :: String -> Bool
+isSmall = all isLower
+isBig = not . isSmall
+
+-- Parse the input file
+
+graphP = edgeP `sepBy` endOfLine
+edgeP = (,) <$> (many1 letter <* "-") <*> many1 letter
+
+-- successfulParse :: Text -> (Integer, [Maybe Integer])
+successfulParse input = 
+  case parseOnly graphP input of
+    Left  _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
+    Right graph -> graph
diff --git a/data/advent12.txt b/data/advent12.txt
new file mode 100644 (file)
index 0000000..e408c73
--- /dev/null
@@ -0,0 +1,24 @@
+by-TW
+start-TW
+fw-end
+QZ-end
+JH-by
+ka-start
+ka-by
+end-JH
+QZ-cv
+vg-TI
+by-fw
+QZ-by
+JH-ka
+JH-vg
+vg-fw
+TW-cv
+QZ-vg
+ka-TW
+ka-QZ
+JH-fw
+vg-hu
+cv-start
+by-cv
+ka-cv
diff --git a/data/advent12a.txt b/data/advent12a.txt
new file mode 100644 (file)
index 0000000..898cd56
--- /dev/null
@@ -0,0 +1,7 @@
+start-A
+start-b
+A-c
+A-b
+b-d
+A-end
+b-end
\ No newline at end of file
diff --git a/data/advent12c.txt b/data/advent12c.txt
new file mode 100644 (file)
index 0000000..65f3833
--- /dev/null
@@ -0,0 +1,18 @@
+fs-end
+he-DX
+fs-he
+start-DX
+pj-DX
+end-zg
+zg-sl
+zg-pj
+pj-he
+RW-he
+fs-DX
+pj-RW
+zg-RW
+start-pj
+he-WI
+zg-he
+pj-fs
+start-RW