1 {-# LANGUAGE OverloadedStrings #-}
6 import Data.Text (Text)
7 import qualified Data.Text.IO as TIO
9 import Data.Void (Void)
11 import Text.Megaparsec
12 import Text.Megaparsec.Char
13 import qualified Text.Megaparsec.Char.Lexer as L
14 import qualified Control.Applicative as CA
17 data Tree a = Node [Tree a] a deriving (Eq, Show)
19 instance Foldable Tree where
20 foldMap f (Node (t: ts) m) = f m <> foldMap (foldMap f) ts
25 text <- TIO.readFile "data/advent08-small.txt"
26 let treeSpec = successfulParse text
27 let (tree, _) = parseTree treeSpec
28 print $ foldMap id tree
32 -- part1 = foldMap sum
33 part1 = metadataOfTree
38 parseTree (c:m:spec) = (Node children metadata, remainder')
39 where (children, remainder) = parseManyTree c spec
40 metadata = take m remainder
41 remainder' = drop m remainder
45 | otherwise = ((tree:otherTrees), remainder')
46 where (tree, remainder) = parseTree spec
47 (otherTrees, remainder') = parseManyTree (n-1) remainder
49 metadataOfTree (Node trees metadata) = metadata ++ (concatMap metadataOfTree trees)
51 valueOfTree (Node trees metadata)
52 | null trees = sum metadata
53 | otherwise = sum selectedValues
54 where childValues = map valueOfTree trees
55 selectedValues = map (\v -> childValues!!(v-1)) $ filter (<= (length trees)) metadata
58 -- Parse the input file
60 type Parser = Parsec Void Text
63 sc = L.space (skipSome spaceChar) CA.empty CA.empty
64 -- sc = L.space (skipSome (char ' ')) CA.empty CA.empty
67 integer = lexeme L.decimal
69 treeFileP = many integer
71 successfulParse :: Text -> [Int]
72 successfulParse input =
73 case parse treeFileP "input" input of
74 Left _error -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
75 Right treeSpec -> treeSpec