75 lines
1.7 KiB
Haskell
75 lines
1.7 KiB
Haskell
|
{-# LANGUAGE OverloadedStrings #-}
|
||
|
{-# OPTIONS_GHC -Wno-name-shadowing #-}
|
||
|
|
||
|
module Day3 where
|
||
|
|
||
|
-- import Debug.Trace
|
||
|
|
||
|
import Data.String
|
||
|
import Data.Scientific (coefficient)
|
||
|
import Data.Attoparsec.Text (Parser)
|
||
|
import Data.Either (fromRight)
|
||
|
import Data.Maybe (catMaybes)
|
||
|
import qualified Data.Attoparsec.Text as P
|
||
|
import qualified Data.Text.IO as T
|
||
|
|
||
|
type Program = [Inst]
|
||
|
|
||
|
data Inst = IMult Integer Integer | IDo | IDont
|
||
|
deriving Show
|
||
|
|
||
|
parseInput :: Parser Program
|
||
|
parseInput =
|
||
|
catMaybes <$>
|
||
|
P.many1' (P.choice [ Just <$> parseMult
|
||
|
, Just <$> parseDo
|
||
|
, Just <$> parseDont
|
||
|
, Nothing <$ P.anyChar])
|
||
|
<* P.endOfInput
|
||
|
|
||
|
parseDo :: Parser Inst
|
||
|
parseDo = IDo <$ "do()"
|
||
|
|
||
|
parseDont :: Parser Inst
|
||
|
parseDont = IDont <$ "don't()"
|
||
|
|
||
|
parseMult :: Parser Inst
|
||
|
parseMult = do
|
||
|
_ <- "mul("
|
||
|
n1 <- toInteger . coefficient <$> P.scientific
|
||
|
_ <- ","
|
||
|
n2 <- toInteger . coefficient <$> P.scientific
|
||
|
_ <- ")"
|
||
|
pure $ IMult n1 n2
|
||
|
|
||
|
solveA :: Program -> Integer
|
||
|
solveA = sum . fmap mult
|
||
|
|
||
|
mult :: Inst -> Integer
|
||
|
mult (IMult n1 n2) = n1 * n2
|
||
|
mult _ = 0
|
||
|
|
||
|
solveB :: Program -> Integer
|
||
|
solveB = sum . fmap mult . cleanup
|
||
|
where
|
||
|
cleanup (x@(IMult _ _):xs) = x:cleanup xs
|
||
|
cleanup (IDo:xs) = cleanup xs
|
||
|
cleanup (IDont:xs) = forget xs
|
||
|
cleanup [] = []
|
||
|
forget ((IMult _ _):xs) = forget xs
|
||
|
forget (IDo:xs) = cleanup xs
|
||
|
forget (IDont:xs) = forget xs
|
||
|
forget [] = []
|
||
|
|
||
|
input :: IsString s => s
|
||
|
input = "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
|
||
|
|
||
|
main :: IO ()
|
||
|
main = do
|
||
|
input <- T.readFile "inputs/day3.input"
|
||
|
putStrLn "Part 1"
|
||
|
let xs = fromRight [] $ P.parseOnly parseInput input
|
||
|
print $ solveA xs
|
||
|
putStrLn "Part 2"
|
||
|
print $ solveB xs
|