Advertisement
rodneys_mission

day03-mull-it-over.hs

Dec 7th, 2024 (edited)
80
0
165 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env stack
  2. -- stack runghc
  3.  
  4. module Main where
  5. import Data.Functor (($>))
  6. import Data.Void (Void)
  7. import Text.Megaparsec ((<|>), Parsec, anySingle, atEnd, empty, eof, failure, label, lookAhead, many, runParser, takeP, try)
  8. import Text.Megaparsec.Char (char, newline, string)
  9. import Text.Megaparsec.Char.Lexer (decimal)
  10.  
  11. -- Test:
  12. --  % echo -e 'xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))' | ./day03-mull-it-over.hs # = 161
  13.  
  14. data Instruction = MulInstr Int Int deriving (Show)
  15.  
  16. type Parser = Parsec Void String
  17.  
  18. instrs :: Parser [Instruction]
  19. instrs = many instr <* eof
  20.  
  21. mulinstr :: Parser Instruction
  22. mulinstr = string "mul(" *> (MulInstr <$> (decimal <* char ',') <*> (decimal <* char ')'))
  23.  
  24. instr :: Parser Instruction
  25. instr = newline $> MulInstr 0 0
  26.         <|> try mulinstr
  27.         <|> anySingle *> instr
  28.  
  29. -- How can this work? I don't want to match on newlines and insert dummy multiplications.
  30. -- But this yields a `TrivialError 72 (Just EndOfInput)`; how do I break out of the 'many' parser?
  31. instr' :: Parser Instruction
  32. instr' = try mulinstr
  33.          <|> anySingle *> instr
  34.  
  35. solve :: Either a [Instruction] -> Int
  36. solve (Right is) = sum [op1 * op2 | MulInstr op1 op2 <- is]
  37.  
  38. main :: IO ()
  39. main = interact $ show . solve . runParser instrs "<stdin>"
  40.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement