96ff8944698d04a8f1fa3fc60b4300345755efd2
[advent-of-code-18.git] / src / advent20 / advent20.hs
1 {-# LANGUAGE NegativeLiterals #-}
2 {-# LANGUAGE OverloadedStrings #-}
3
4
5 -- import Debug.Trace
6
7 -- import Prelude hiding ((++))
8 import Data.Text (Text)
9 import qualified Data.Text as T
10 import qualified Data.Text.IO as TIO
11
12 import Data.Void (Void)
13 import Text.Megaparsec hiding (State)
14 import Text.Megaparsec.Char
15 import qualified Text.Megaparsec.Char.Lexer as L
16 import qualified Control.Applicative as CA
17
18 import qualified Data.Map.Strict as M
19 import Data.Map.Strict ((!))
20 import qualified Data.Set as S
21
22 import Linear (V2(..))
23
24 import Control.Monad.State.Lazy
25
26 type Coord = V2 Integer -- x, y, with north and east incresing values (origin a bottom left)
27 data Door = Door Coord Coord deriving (Show, Eq, Ord)
28 type Doors = S.Set Door
29
30 makeDoor :: Coord -> Coord -> Door
31 makeDoor a b
32 | a < b = Door a b
33 | otherwise = Door b a
34
35
36
37
38 main :: IO ()
39 main = do
40 text <- TIO.readFile "data/advent20.txt"
41 print $ T.length text
42 -- let (ip, instrs) = successfulParse text
43 -- print (ip, instrs)
44 -- -- print $ part1 ip instrs
45 -- print $ sum [i | i <- [1..1032], 1032 `mod` i == 0]
46 -- -- print $ part2 ip instrs
47 -- print $ sum [i | i <- [1..10551432], 10551432 `mod` i == 0]
48
49
50
51 -- type Parser = Parsec Void Text
52 type Parser = ParsecT Void Text (StateT [Coord] [])
53
54
55 sc :: Parser ()
56 sc = L.space (skipSome spaceChar) CA.empty CA.empty
57
58 lexeme = L.lexeme sc
59 -- integer = lexeme L.decimal
60 symb = L.symbol sc
61 branchSepP = symb "|"
62 openBranchP = symb "("
63 closeBranchP = symb ")"
64 startP = symb "^"
65 endP = symb "$"
66
67 doorP :: Parser Coord
68 doorP = nP <|> sP <|> eP <|> wP
69 nP = (symb "N" *> pure (V2 0 1))
70 sP = (symb "S" *> pure (V2 0 -1))
71 eP = (symb "E" *> pure (V2 1 0))
72 wP = (symb "W" *> pure (V2 -1 0))
73
74 -- instructionFileP = (startP `between` endP) branchesP
75
76 -- branchesP :: MyParser Doors
77 -- branchesP = fmap S.unions . many $ choiceP <|> pathP
78
79 -- choiceP :: MyParser Doors
80 -- choiceP = (openBranchP `between` closeBranchP) $ do
81 -- here <- get
82 -- return fmap S.unions (`sepBy` branchSepP) $ do
83 -- put here
84 -- return branchesP
85
86
87
88 -- pathP :: MyParser Doors
89 -- pathP = S.fromList <$> many stepP
90 pathP = many stepP
91
92 -- stepP :: MyParser Door
93 stepP = do
94 heres <- get
95 delta <- doorP
96 let theres = map (+delta) heres
97 put theres
98 return (map (\h -> makeDoor h (h + delta)) heres)
99
100 -- choiceP :: MyParser [Door]
101 -- choiceP = (openBranchP `between` closeBranchP) $ do
102 -- heres <- get
103 -- do
104 -- here <- heres
105 -- put [here]
106 -- branch <- (pathP `sepBy` branchSepP)
107 -- return branch
108
109 -- fmap concat $ (`sepBy` branchSepP) $ do
110 -- here <- heres
111 -- pathP
112
113
114 {- heres <- get
115 choices <- (`sepBy` branchSepP) $ do
116 put heres
117 pathP
118 return $ concat choices -- (S.unions choices)-}
119
120 -- choiceOrPathP = many (choiceP <|> pathP)
121
122
123 -- successfulParse :: Text -> (Integer, [Instruction])
124 -- successfulParse input =
125 -- case parse instructionsP "input" input of
126 -- Left _error -> (0, []) -- TIO.putStr $ T.pack $ parseErrorPretty err
127 -- Right instructions -> instructions