--- /dev/null
+-- Writeup at https://work.njae.me.uk/2024/12/03/advent-of-code-2024-day-3/
+
+import AoC
+import Data.List
+import Data.Text (Text)
+import qualified Data.Text.IO as TIO
+import Data.Attoparsec.Text hiding (take)
+
+
+data Term = Mul Int Int
+ | Junk Char
+ | DoTerm
+ | DontTerm
+ deriving (Eq, Show)
+
+main :: IO ()
+main =
+ do dataFileName <- getDataFileName
+ text <- TIO.readFile dataFileName
+ let program = successfulParse text
+ -- print program
+ -- print $ filter notJunk program
+ -- print $ enabledMuls program
+ print $ part1 program
+ print $ part2 program
+
+part1, part2 :: [Term] -> Int
+-- part1 program = sum $ fmap evalTerm program
+-- part2 program = sum $ fmap evalTerm $ enabledMuls program
+part1 = sum . fmap evalTerm
+part2 = sum . fmap evalTerm . enabledMuls
+
+-- notJunk :: Term -> Bool
+-- notJunk (Mul _ _) = True
+-- notJunk DoTerm = True
+-- notJunk DontTerm = True
+-- notJunk _ = False
+
+evalTerm :: Term -> Int
+evalTerm (Mul a b) = a * b
+evalTerm _ = 0
+
+enabledMuls :: [Term] -> [Term]
+enabledMuls terms = snd $ foldl' go (True, []) terms
+ where go (True, ts) (Mul a b) = (True, Mul a b : ts)
+ go (_, ts) DontTerm = (False, ts)
+ go (_, ts) DoTerm = (True, ts)
+ go (c, ts) _ = (c, ts)
+
+-- Parse the input file
+
+junkP, doP, dontP, mulP :: Parser Term
+termsP :: Parser [Term]
+
+junkP = Junk <$> anyChar
+-- junksP = Junks <$> many1 anyChar
+doP = DoTerm <$ "do()"
+dontP = DontTerm <$ "don't()"
+mulP = Mul <$> ("mul(" *> decimal <* ",") <*> decimal <* ")"
+
+-- termsP = (++) <$> (many' junksP) <*> (mulP `sepBy` junksP)
+termsP = many' (choice [mulP, doP, dontP, junkP])
+
+successfulParse :: Text -> [Term]
+successfulParse input =
+ case parseOnly termsP input of
+ Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
+ Right matches -> matches
+
executable advent02
import: warnings, common-extensions, build-directives, common-modules
main-is: advent02/Main.hs
-
\ No newline at end of file
+
+executable advent03
+ import: warnings, common-extensions, build-directives, common-modules
+ main-is: advent03/Main.hs
+ build-depends: attoparsec, text