From 3c8880f27a53ab063886a0b19b665c85155cbaf2 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sun, 5 Jan 2020 20:19:06 +0000 Subject: [PATCH] Part 1 done --- advent20/package.yaml | 62 ++++++++ advent20/src/advent20.hs | 322 +++++++++++++++++++++++++++++++++++++++ data/advent20.txt | 119 +++++++++++++++ data/advent20a.txt | 19 +++ data/advent20b.txt | 37 +++++ stack.yaml | 1 + 6 files changed, 560 insertions(+) create mode 100644 advent20/package.yaml create mode 100644 advent20/src/advent20.hs create mode 100644 data/advent20.txt create mode 100644 data/advent20a.txt create mode 100644 data/advent20b.txt diff --git a/advent20/package.yaml b/advent20/package.yaml new file mode 100644 index 0000000..6e91ce6 --- /dev/null +++ b/advent20/package.yaml @@ -0,0 +1,62 @@ +# This YAML file describes your package. Stack will automatically generate a +# Cabal file when you run `stack build`. See the hpack website for help with +# this file: . + +name: advent20 +synopsis: Advent of Code +version: '0.0.1' + +default-extensions: +- AllowAmbiguousTypes +- ApplicativeDo +- BangPatterns +- BlockArguments +- DataKinds +- DeriveFoldable +- DeriveFunctor +- DeriveGeneric +- DeriveTraversable +- EmptyCase +- FlexibleContexts +- FlexibleInstances +- FunctionalDependencies +- GADTs +- GeneralizedNewtypeDeriving +- ImplicitParams +- KindSignatures +- LambdaCase +- MonadComprehensions +- MonoLocalBinds +- MultiParamTypeClasses +- MultiWayIf +- NegativeLiterals +- NumDecimals +# - OverloadedLists +- OverloadedStrings +- PartialTypeSignatures +- PatternGuards +- PatternSynonyms +- PolyKinds +- RankNTypes +- RecordWildCards +- ScopedTypeVariables +- TemplateHaskell +- TransformListComp +- TupleSections +- TypeApplications +- TypeInType +- TypeOperators +- ViewPatterns + + +executables: + advent20: + main: advent20.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - containers + - pqueue + - mtl + - lens diff --git a/advent20/src/advent20.hs b/advent20/src/advent20.hs new file mode 100644 index 0000000..0e2516a --- /dev/null +++ b/advent20/src/advent20.hs @@ -0,0 +1,322 @@ +import Debug.Trace + +-- import qualified Data.Text.IO as TIO + +-- import qualified Data.Map.Strict as M +-- import Data.Map.Strict ((!)) +import qualified Data.PQueue.Prio.Min as P +import qualified Data.Set as S +import qualified Data.Sequence as Q +import Data.Sequence ((<|)) -- , (|>), (><)) +import Data.Foldable (foldl', any, sum) -- (toList, foldr', foldl', all) +import Data.Char +import Control.Monad.Reader +import Control.Lens hiding ((<|), (|>)) +import Data.Maybe (fromMaybe) + + + +type Position = (Int, Int) -- r, c + +data Portal = Portal { _label :: String + , _position :: Position + } deriving (Eq, Ord, Show) +makeLenses ''Portal + +type Portals = S.Set Portal + + +type ExpandedMaze = S.Set Position +data MazeComplex = MazeComplex + { _mazeE :: ExpandedMaze + , _portalsE :: Portals + , _portalLocs :: S.Set Position + } deriving (Eq, Ord, Show) +makeLenses ''MazeComplex + +type EdgeConnects = (Portal, Portal) +data EdgeType = Walk | Teleport deriving (Eq, Ord, Show) + +data Edge = Edge { _connects :: EdgeConnects + , _edgeType :: EdgeType + , _distance :: Int + } deriving (Eq, Ord, Show) +makeLenses ''Edge + +type Maze = S.Set Edge + +type MazeContext = Reader Maze + +type ExploredStates = S.Set Portal + +data Agendum = Agendum { _current :: Portal + , _trail :: Q.Seq Edge + , _cost :: Int} deriving (Show, Eq) +makeLenses ''Agendum + +type Agenda = P.MinPQueue Int (Agendum) + + +main :: IO () +main = do + -- text <- readFile "data/advent20a.txt" + -- let mc = buildComplex text + -- print mc + -- let maze = contractMaze mc + -- print maze + maze <- setup + putStrLn $ showContracted maze + print $ part1 maze + -- 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 + + + +setup = do + text <- readFile "data/advent20.txt" + let mc = buildComplex text + -- print mc + return $ contractMaze mc + -- print maze + + +-- part1 :: Maze -> Int +part1 maze = result -- maybe 0 _cost result + where result = runReader searchMaze maze + + + +buildComplex :: String -> MazeComplex +buildComplex text = mc & portalLocs .~ pLocs + where mc = foldl' (buildMazeRow rows) mc0 [0..l] + mc0 = MazeComplex {_mazeE = S.empty, _portalsE = S.empty, _portalLocs = S.empty} + rows = lines text + l = length rows - 1 + pLocs = S.map _position (mc ^. portalsE) + +buildMazeRow :: [String] -> MazeComplex -> Int -> MazeComplex +buildMazeRow rows mc r = foldl' (buildMazeCell rows r) mc [0..l] + where l = length (rows!!r) - 1 + + +buildMazeCell :: [String] -> Int -> MazeComplex -> Int -> MazeComplex +buildMazeCell rows r mc c + | char == '.' = mc' + | isUpper char = mc & portalsE .~ portals' + | otherwise = mc + where char = (rows!!r)!!c + mc' = mc & mazeE %~ (S.insert here) + here = (r, c) + portals' = makePortal (mc ^. portalsE) rows char r c + + +makePortal portals rows hc r c + | isUpper rc = if pr == '.' + then S.insert (Portal [hc, rc] (r, c + 2)) portals + else S.insert (Portal [hc, rc] (r, c - 1)) portals + | isUpper dc = if pd == '.' + then S.insert (Portal [hc, dc] (r + 2, c)) portals + else S.insert (Portal [hc, dc] (r - 1, c)) portals + | otherwise = portals + where -- lc = charAt rows r (c - 1) + rc = charAt rows r (c + 1) + -- uc = charAt rows (r - 1) c + dc = charAt rows (r + 1) c + -- pu = charAt rows (r - 1) c + pd = charAt rows (r + 2) c + -- pl = charAt rows r (c - 1) + pr = charAt rows r (c + 2) + +charAt :: [String] -> Int -> Int -> Char +charAt rows r c = atDef ' ' (atDef "" rows r) c + +atDef :: a -> [a] -> Int -> a +atDef x xs i = fromMaybe x $ atMaybe xs i +-- atDef x = (fromMaybe x) . atMaybe + +atMaybe :: [a] -> Int -> Maybe a +atMaybe xs i + | i < 0 = Nothing + | i >= (length xs) = Nothing + | otherwise = Just (xs!!i) + + +contractMaze :: MazeComplex -> Maze +contractMaze expanded = S.union mazeW mazeP + where starts = expanded ^. portalsE + mazeW = S.foldr (contractFrom expanded) S.empty starts + mazeP = S.foldr (addWarp starts) S.empty starts + + +contractFrom :: MazeComplex -> Portal -> Maze -> Maze +contractFrom expanded start maze0 = S.union maze0 reachables + where startPos = start ^. position + reachables = reachableFrom [(startPos, 0)] S.empty expanded' start + expanded' = expanded & portalsE %~ (S.delete start) + & portalLocs %~ (S.delete startPos) + -- & mazeE %~ (S.delete startPos) + +reachableFrom :: [(Position, Int)] -> (S.Set Position) -> MazeComplex -> Portal -> Maze +reachableFrom [] _closed _expanded _start = S.empty +reachableFrom ((here, distance):boundary) closed expanded start + | here `S.member` closed = reachableFrom boundary closed expanded start + | here `S.member` ps = S.insert edge $ reachableFrom boundary closed' expanded start + | otherwise = reachableFrom boundary' closed' expanded start + where nbrs0 = S.intersection (expanded ^. mazeE) $ possibleNeighbours here + nbrs = S.difference nbrs0 closed + closed' = S.insert here closed + ps = expanded ^. portalLocs + other = S.findMin $ S.filter (\p -> p ^. position == here) $ expanded ^. portalsE + edge = Edge { _connects = mkConnection start other, _edgeType = Walk, _distance = distance } + neighbours = S.map (\n -> (n, distance + 1)) nbrs + boundary' = boundary ++ (S.toAscList neighbours) + + +addWarp :: Portals -> Portal -> Maze -> Maze +addWarp portals portal warps + | S.null others = warps + | otherwise = S.insert warp warps + where others = S.filter (portalsConnect lab pos) portals + lab = portal ^. label + pos = portal ^. position + other = S.findMin others + warp = Edge {_connects = mkConnection portal other, _edgeType = Teleport, _distance = 1} + + +portalsConnect :: String -> Position -> Portal -> Bool +portalsConnect lab pos portal = (pLabel == lab) && (not (pPos == pos)) + where pLabel = portal ^. label + pPos = portal ^. position + + +mkConnection :: Portal -> Portal -> EdgeConnects +mkConnection a b = if a < b then (a, b) else (b, a) + +edgeTouches :: Portal -> Edge -> Bool +edgeTouches p e + | p == a = True + | p == b = True + | otherwise = False + where (a, b) = e ^. connects + +-- anyEdgeTouch :: S.Set Portal -> Edge -> Bool +-- -- anyEdgeTouch xs e = S.foldl' (\t x -> t || (edgeTouches e x)) False xs +-- anyEdgeTouch xs e = any (edgeTouches e) xs + +edgeOther :: Portal -> Edge -> Portal +edgeOther x e + | x == a = b + | otherwise = a + where (a, b) = e ^. connects + +possibleNeighbours :: Position -> S.Set Position +possibleNeighbours (r, c) = S.fromList [(r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)] + + +mazePortals edges = S.foldr' mps S.empty edges + where mps e ps = let (p1, p2) = e ^. connects + in S.insert p1 $ S.insert p2 ps + + + +searchMaze :: MazeContext (Maybe (Agendum)) +searchMaze = + do agenda <- initAgenda + aStar agenda S.empty + +initAgenda :: MazeContext (Agenda) +initAgenda = + do edges <- ask + let portals = mazePortals edges + let portal = S.findMin $ S.filter (\p -> p ^. label == "AA") portals + cost <- estimateCost portal + return $ P.singleton cost Agendum { _current = portal, _trail = Q.empty, _cost = cost} + + +aStar :: Agenda -> ExploredStates -> MazeContext (Maybe (Agendum)) +aStar agenda closed + -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMin agenda) ) False = undefined + | P.null agenda = return Nothing + | otherwise = + do let (_, currentAgendum) = P.findMin agenda + let reached = _current currentAgendum + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_cost a) a q) (P.deleteMin agenda) nexts + reachedGoal <- isGoal reached + if reachedGoal + then return (Just currentAgendum) + else if reached `S.member` closed + then aStar (P.deleteMin agenda) closed + else aStar newAgenda (S.insert reached closed) + + +isGoal :: Portal -> MazeContext Bool +isGoal portal = return $ portal ^. label == "ZZ" + +candidates :: Agendum -> ExploredStates -> MazeContext (Q.Seq (Agendum)) +candidates agendum closed = + do let candidate = agendum ^. current + let previous = agendum ^. trail + succs <- successors candidate + let nonloops = Q.filter (\s -> not $ (fst s) `S.member` closed) succs + mapM (makeAgendum previous) nonloops + +makeAgendum :: (Q.Seq Edge) -> (Portal, Edge) -> MazeContext (Agendum) +makeAgendum previous (newP, newE) = + do predicted <- estimateCost newP + let incurred = (newE ^. distance) + (sum $ fmap (^. distance) previous) + return Agendum { _current = newP + , _trail = newE <| previous + , _cost = incurred + predicted + } + +successors :: Portal -> MazeContext (Q.Seq (Portal, Edge)) +successors portal = + do maze <- ask + let edges = S.filter (edgeTouches portal) maze + let locations = S.map (\e -> (edgeOther portal e, e)) edges + let succs = S.foldr' (<|) Q.empty locations + return succs + +estimateCost :: Portal -> MazeContext Int +estimateCost portal = return 0 + -- do let heres = explorer ^. position + -- ks <- asks _keys + -- cavern <- asks _cave + -- let kH = explorer ^. keysHeld + -- let unfound = ks `S.difference` kH + -- let unfoundEdges0 = S.filter (\e -> edgeTouch heres e) cavern + -- let unfoundEdges = S.filter (\e -> not $ anyEdgeTouch kH e) unfoundEdges0 + -- let furthest = S.findMax $ S.insert 0 $ S.map _distance unfoundEdges + -- return $ max 0 $ furthest + (S.size unfound) - 1 + + + + + + +showContracted :: Maze -> String +showContracted maze = "graph Maze {\n" ++ bulk ++ "\n}" + where bulk = S.foldr (\e s -> (showEdge e) ++ s) "" maze + +showEdge :: Edge -> String +showEdge e = (showPortal h) ++ " -- " ++ (showPortal t) ++ " [ label = \"" ++ (edgeLabel e) ++ "\"];\n" + where edgeLabel e = (show (e ^. edgeType)) ++ ", " ++ (show (e ^. distance)) + (h, t) = e ^. connects + showPortal p = p ^. label ++ (show (fst (p ^. position))) ++ "c" ++ (show (snd (p ^. position))) diff --git a/data/advent20.txt b/data/advent20.txt new file mode 100644 index 0000000..f6c4407 --- /dev/null +++ b/data/advent20.txt @@ -0,0 +1,119 @@ + C T N Z D C X P + Y L Z Z M V Z P + ###################################.###########.#####.#.#######.###.#######.#.####################################### + #.#.#.#.#.#...#.......#...#.........#...#...........#.#.....#.....#.......#...............#.............#...#.......# + #.#.#.#.#.###.#.###.###.###.###.###.#.#.###.#.###.###.#.#.#####.#.#.###.#########.###.#####.#.###.###.#####.#####.### + #.....#...#.....#.#.........#...#.....#...#.#.#...#.#...#.#.....#.#.#.#.....#.......#...#...#...#...#.#.....#...#.#.# + #####.###.#######.###.#.#.###.###.#.###.#########.#.#.###.#.#########.###.#####.#####.#####.#########.###.###.###.#.# + #...........#.......#.#.#.#...#...#.#.......#.......#.#...#.......#.#.........#.#.#.....#.#.......#.#.#.......#.....# + #####.#.#.#######.#.###.#####.#####.#####.#######.###.###.###.#####.#.###.#####.#.###.###.#.#.#####.#####.#.###.#.### + #.....#.#.....#.#.#.#.#...#...#.....#.....#.#.#.....#...#...#...#.......#...#.#...#.#.......#...#.#...#...#.#...#...# + #.#.#.#.#####.#.###.#.###########.#######.#.#.###.#.#####.#####.###.#.###.#.#.#.###.#.###.#######.#.#####.#####.##### + #.#.#.#.#.#.#.........#...#...#...#.#.#...#...#.#.#...#...#...#...#.#...#.#.#.#...#.....#.....#.#.....#...#.#...#...# + #.#.#.#.#.#.#.###.#.#.###.###.#####.#.#.###.#.###.#.###.#.###.###.#.#########.#.#######.#.#.###.#.#.#####.#.#.#.###.# + #.#.#.#.#.....#.#.#.#.#.....#.......#.#.#...#.....#...#.#.#.....#.#.....#...#.........#.#.#...#...#.#...#.....#.#...# + #######.#######.#####.###.###.#####.#.#.###.###.#.#######.###.#.#.#.#####.###.#######.###.#####.#.###.###.#.#.###.#.# + #.#...#.#.#.#...#...#...#.#.#.#...#.#...#.....#.#.#...#...#.#.#...#...#...#.......#.....#.......#...#...#.#.#.#.#.#.# + #.###.###.#.#.#.#.###.###.#.#####.#.#.#.###.#######.#####.#.#.#.#.#.###.###.#############.#.###.#######.#.#####.###.# + #.#.....#.....#.................#.....#.#.#...#.....#.#.#.#...#.#.#.....#.#.#...#.....#...#.#.#.#...#.......#...#...# + #.###.#.###.#####.#.#.#.#####.###.#.#.###.#.#.###.#.#.#.#.#.#.#.#####.###.#.#.###.###########.#####.###.#######.###.# + #...#.#.#...#.....#.#.#.#...#.#...#.#.#.....#...#.#.....#.#.#.#...#...#...#...#.#.#.#.....#...#.....#.....#.#.....#.# + ###.#.###.#.###.#.#########.#.###.#.###.###.#.#####.###.#.#.#######.#####.#.###.#.#.#.#######.#####.###.###.###.###.# + #...#.#.#.#.#...#.#...#.........#.#.#...#.#.#.#.......#.#.#.....#...#.....#...........#.#.#.#.#.#.....#...#.#.....#.# + ###.#.#.#######.#####.#######.#####.#####.#.#########.#.#.###.#####.#.###.#.#.#.###.###.#.#.#.#.#.#.###.###.#.#####.# + #.........#...#...#.#.#.............#...#.......#.....#...#.......#.#.#...#.#.#...#.....#...#.#...#...#.#...#.#.#.#.# + #####.#.###.#######.#.#####.#######.#.###.#.#.###.#.#######.#######.#.#.###.#.#.#########.###.###.#####.#.###.#.#.#.# + #.....#...#.....#.#...#.....#.#.#.....#...#.#.#.#.#.......#...#...#.#.#.#.#.#.#...#...#...#.........#...#.#...#.#.#.# + #####.#.#####.###.#.#########.#.###.#####.#.###.#########.#.###.###.#.#.#.#.#########.###.###.#########.#.###.#.#.#.# + #...#.#.#.#.......#.#.#.....#.#.........#.#...#...#.......#.......#.#.#...#.#.#...#...#...........#...#.#.....#.....# + ###.###.#.###.###.#.#.#.###.#.###.#.#######.###.###.#######.###.###.#.###.#.#.###.#.#.#######.#####.###.#.#.###.#.### + #.......#.#.#...#.#...#.#...#.#...#.#.....#.....#.#.....#.#...#.#.#.#.#.#.#...#...#.#.....#.....#.#.#...#.#...#.#...# + #####.#.#.#.#####.#.#######.#.#####.#.#####.#.###.###.#.#.#.#####.#.#.#.#.#.###.#####.#######.###.#.#.#####.###.##### + #...#.#.......#.......#...................#.#...#.....#.#.........#...#...#...........#.#.......#.#...#.#.....#...#.# + ###.###.#######.###.#################.#####.###########.#######.#######.#####.#.#######.#.#####.#.###.#.###.###.#.#.# + #.#...#.#.#...#.#...#.#.....#.# G U U G Y P J #...#.....#.#.#.#...#.#.#.#.#.# + #.###.#.#.#.#.#####.#.###.###.# Y M C C O Y V ###.#####.#.#.#.###.#.#.#.###.# +UM....#...#.#.#.#...#.#.#.......# #.#.#.#...#.........#.........# + #.#####.#.#.#####.#.#.#.#.#.### #.###.#.#.#.#.#.###.#.###.#.### + #.............#...#.#.#.#.#.#..LM #.#...#.#.#.#.#...#.....#.#.#.# + #.###.#####.#####.#.#.#.#.###.# #.#.###.#.#.###.###.#.###.###.# + #...#.#...#.............#.....# TL..#.....#.....#.#...#.#...#.#.# + #########.###########.###.##### #.#####.#.###########.###.#.#.# + #...#...............#.#.#.#...# #.......#...#.......#.#........PY + #.###.#.###.#.###.#####.###.### #############.#.#.############# +YO......#.#...#...#.#.......#...# WH..#.#.#.#.#.#.#.#...#.#.......# + #.#.#.#.#.#.#####.#.#.#####.### #.#.#.#.#.#.#####.#.#.###.#.### + #.#.#.#.#.#.#.......#.#.#.#.#..AM #.#.#...#.#.#.....#.#.#...#....KK + #######.###.#####.###.#.#.#.#.# #.#.#.###.#.#####.#.#.#.###.### + #...#...#...#.#.....#.........# #.......#.....#.#.#.....#...#.# + #.###########.#############.### #####.#.###.#.#.#.###.###.#.#.# + #...#.#...#.#...#.........#.#..XI #...#.#.....#.....#.....#.#.#.# + #.###.#.###.###.#.###.#######.# ###.###.#####################.# + #.#...#.#...#.#.#.#.....#.....# #...#.#.#...#.#.........#.....# + #.#.###.#.#.#.#.#.#.#####.##### ###.#.###.###.#.#.#.###.#.###.# +AW..........#.......#...........# #.#.....#...#...#.#.#.....#...# + ############################### #.#.###.#.#.#.#.###.###.###.### + #.......#.....................# CV..#...#...#...#...#...#.#.....# + ###.###.#.###.###.#.#.###.###.# #.###.###.#.#.###.###########.# + #...#...#...#.#...#.#.#...#.#..HB #.....#...#.#.#.#.#.#.....#.#..CQ + ###.#.#####.#.#####.#####.#.#.# #.###.###.#####.###.###.###.### +GL..#.#.....#.#.#...#.#...#...#.# #...#...#.#.#...#...#.#.......# + #.#.#.#.#.#.#####.###.######### ###########.###.#.#.#.#.#####.# + #...#.#.#.....#.#.......#.#...# #...#.#.........#.#...#.....#.# + ###############.#.#######.#.### ###.#.#####.###.#####.#####.#.# +PN....#.................#.....#.# #.#.....#.#...#.#...........#..JV + #.#.#.###.#.#########.###.#.#.# #.###.###.#.#.#####.#.#.###.### + #.#.#...#.#.#.........#...#.#..NZ CY............#.......#.#.#.#.#.# + ###.###.###.#.###.#######.#.#.# #######.#######.#########.###.# + #.....#...#.#.#.....#...#.#.#.# DM......#.#...#...#.#...#...#....AM + #.#.###.###########.#.#.#.#.#.# ###.#####.#.#####.#.###.#.#.#.# + #.#...........#.......#...#...# #.#.#...#.#...#.#.......#.#.#.# + ###############.###########.#.# #.#.###.#.#.###.###.#.###.#.### + #.#.....#.....#.#.......#.#.#.# #...#.....#...#...#.#.#...#...# + #.#.#.###.#######.###.###.###.# #.#.###.###.#.###.#.###.#####.# + #...#.#.#...#.#.#...#.......#.# #.#.......#.#.........#.......# + #.###.#.#.###.#.###.#####.##### #######.#.#.###.#.#####.#.###.# +YF..#.#.........#...#...#...#....PN XZ......#.#.#.#.#.#.#.....#.#.#.# + #.#.#######.###.#.###.###.#.### #####.#####.#.#.###########.### + #.#.#.#.#.......#.......#.....# #.........#.#.#.#.#...........# + ###.#.#.###.#######.#.######### #.###########.###.#.###.####### + #.......#...#.#...#.#...#.#....KY #.......#.#.....#...#.#.......# + #####.#.#####.#.#########.###.# #.#.###.#.###.###.###.#.####### +YA..#...#.....#.#...#...#.#.....# #.#...#.............#..........KY + #.###.###.###.#.#.#.#.#.#.##### #.#########.#.#.#####.#.#.#.#.# + #.......#.......#...#.........# #...#.......#.#.#.#...#.#.#.#.# + #.#######.###.###.#.#.#.#.###.# A K C G Y Y P #.#######.#.###.#.#######.##### + #.#.......#...#...#.#.#.#...#.# W K Q L A F P #...#.....#...#...#.#.#.......# + #.###.#####.###.#.#.#.#.#.###.#######.#######.###.#######.#######.#####.#####.#################.#.###.###.#.###.#.### + #.#...#...#.#...#.#.#.#.#...#.#.......#.........#.#.#.#.....#.#.#.....#.#.......#.....#...#.#...#...#.......#...#.#.# + #####.###.#######.#####.#.#######.#.#####.#####.#.#.#.#.#####.#.###.###.###.###.#.#.###.###.###.###.#.###.#####.###.# + #.........#...........#.#.......#.#.....#...#.#.#...#.#...........#.#.....#.#.....#.........#.....#.#.#.....#.#.#...# + #####.#######.#####.###.#.###.#####.#.#####.#.#####.#.###.#.#######.#.#.#####.###.#.###.###.#########.###.###.#.###.# + #.......#.....#...#...#.#...#.#...#.#.....#.....#.#.....#.#...#.....#.#.#.#.#.#.#.#...#.#...#...#.......#.....#.#.#.# + #.###.###.#.#.###.#.#####.#.###.#####.#.###.#.#.#.#.#.#####.#####.###.###.#.###.###.#.#####.###.#.###.###.###.#.#.#.# + #...#...#.#.#.#.....#.#...#.#.#...#...#...#.#.#.#...#...#.#.....#...#.#.#...#.......#...#.....#...#...#...#...#.....# + #.#########.#####.#.#.#.#.###.#.#######.#####.#######.###.#.#.###.###.#.###.#######.#.###.#.#.###.###.#####.#######.# + #.....#.......#...#...#.#.#...#...........#.......#.....#...#...#...#.......#.#...#.#.#...#.#.#.#.#.#...#...#.......# + ###.#####.#.###.#.#####.#.###.###.#.#.#.#.###.#.#####.#####.#####.#####.###.#.###.#.#.###.#.###.#.#.#.#.###.###.###.# + #...#.#...#...#.#...#...#.#.#.....#.#.#.#.#...#.#.....#...#.#.......#...#.#...#.#.#.#.#.#.#.....#.#...#.#.#...#...#.# + #.###.###.#.#####.#.#######.#.###.#####.#####.#.#####.###.#.###.###.###.#.#.###.#.#.###.###.#######.#.###.#########.# + #.#.......#...#.#.#.#...#...#.#.#.#.......#...#.#.#.....#.....#...#...#.#.......#...#.#...#.....#.#.#...........#.#.# + #.#.###.#.#####.#.#.###.###.###.#.#.#.#.###.#####.###.###.#.#######.#.#####.#####.#.#.#.#########.###.###.#.#####.### + #.#.#...#.#...#.#.#...#.......#.#.#.#.#...#.....#...#.#.#.#.#.#.#...#...#.....#.#.#.......#.#...#.......#.#.........# + #####.#######.#.#######.###.###.#######.###.#.#####.#.#.###.#.#.###.#.#.###.###.###.#######.#.#####.###.#####.###.#.# + #.......#.........#...#.#.....#...#.#.....#.#.#.......#.#...#.......#.#.#...#...#...............#...#...#.....#...#.# + #####.#####.#.#.#.###.#####.#.#.###.###.#####.#.#######.#.#.#.###.#######.#.###.###.###.#######.#########.###.###.#.# + #.#...#.....#.#.#...#.#.#...#.............#...#.#.......#.#.#...#.#.....#.#.#.....#...#.....#.........#.....#...#.#.# + #.###.###.#########.#.#.#####.###.#.#.###.###.#.#.###.#.#.#####.###.#######.#.###.#.###.#.#.###.#####.###.#.#####.#.# + #.......#.#.................#.#.#.#.#.#...#...#.#.#.#.#.#...#.#.....#.#.....#.#.#.#...#.#.#...#...#...#...#.....#.#.# + ###.#.###.###########.###.#####.#.#########.###.#.#.#.###.###.#####.#.#.###.#.#.#.#.#######.#.#############.#.####### + #.#.#...#.#.#.#...#.....#.#.............#.....#...#.#.#.....#.....#...#.#.#.#.#.#.......#.#.#.#.#.....#...#.#.......# + #.#########.#.#.#########.#.#####.#######.#.#.#######.#####.#.###.#.###.#.#.#.#.#.###.###.#####.###.###.#####.#.#.### + #.#.......#.....#.#.............#.....#...#.#.#.#...#.#.#...#...#...#...#.#.#.#.#...#.....#.#.............#.#.#.#...# + #.#######.#####.#.###.#####.#####.###########.#.#.###.#.###.###.#########.#.#.###.#.#.#####.#.#.#.###.#.###.###.#.#.# + #.#.......#.#.........#.#...#...#.#.#.#.....#.#.......#.....#.#...#.#.......#...#.#.#.........#.#...#.#.......#.#.#.# + #.#####.###.###.#.#.###.#.#####.#.#.#.###.###.#.#.###.#.#.#.#.#.###.###.###.#.#####.#.#.#.#.#.#####.#############.### + #...............#.#.#.....#.........#.........#.#.#...#.#.#.#.........#...#.#.....#.#.#.#.#.#.#.................#...# + ###################################.#####.#####.###########.###.###.#####.###.####################################### + G H W U A X L G + Y B H C A I M C \ No newline at end of file diff --git a/data/advent20a.txt b/data/advent20a.txt new file mode 100644 index 0000000..41d30f0 --- /dev/null +++ b/data/advent20a.txt @@ -0,0 +1,19 @@ + A + A + #######.######### + #######.........# + #######.#######.# + #######.#######.# + #######.#######.# + ##### B ###.# +BC...## C ###.# + ##.## ###.# + ##...DE F ###.# + ##### G ###.# + #########.#####.# +DE..#######...###.# + #.#########.###.# +FG..#########.....# + ###########.##### + Z + Z \ No newline at end of file diff --git a/data/advent20b.txt b/data/advent20b.txt new file mode 100644 index 0000000..5cdd08a --- /dev/null +++ b/data/advent20b.txt @@ -0,0 +1,37 @@ + A + A + #################.############# + #.#...#...................#.#.# + #.#.#.###.###.###.#########.#.# + #.#.#.......#...#.....#.#.#...# + #.#########.###.#####.#.#.###.# + #.............#.#.....#.......# + ###.###########.###.#####.#.#.# + #.....# A C #.#.#.# + ####### S P #####.# + #.#...# #......VT + #.#.#.# #.##### + #...#.# YN....#.# + #.###.# #####.# +DI....#.# #.....# + #####.# #.###.# +ZZ......# QG....#..AS + ###.### ####### +JO..#.#.# #.....# + #.#.#.# ###.#.# + #...#..DI BU....#..LF + #####.# #.##### +YN......# VT..#....QG + #.###.# #.###.# + #.#...# #.....# + ###.### J L J #.#.### + #.....# O F P #.#...# + #.###.#####.#.#####.#####.###.# + #...#.#.#...#.....#.....#.#...# + #.#####.###.###.#.#.#########.# + #...#.#.....#...#.#.#.#.....#.# + #.###.#####.###.###.#.#.####### + #.#.........#...#.............# + #########.###.###.############# + B J C + U P P \ No newline at end of file diff --git a/stack.yaml b/stack.yaml index 9ea2285..4cc915c 100644 --- a/stack.yaml +++ b/stack.yaml @@ -57,6 +57,7 @@ packages: - advent17 - advent18 - advent19 +- advent20 # Dependency packages to be pulled from upstream that are not in the resolver. -- 2.34.1