Main.hs (2682B)
1 module Main (main) where 2 3 import Common.Matrix (Matrix) 4 import Common.Matrix qualified as M 5 import Control.Applicative 6 import Control.Arrow (second, (***)) 7 import Control.Monad 8 import Data.ByteString (ByteString) 9 import Data.ByteString qualified as BS 10 import Data.Char (isDigit, isSpace, ord) 11 import Data.Functor ((<$)) 12 import Data.List (transpose, unsnoc) 13 import Data.List.Split (splitWhen) 14 import Data.Maybe (mapMaybe) 15 import Safe (headMay) 16 import Sparsec 17 import System.Exit (die) 18 19 -------------------------------------------------------------------------------- 20 -- Solution 21 22 data Operand = Digit Int | Space deriving (Show) 23 data Operator = Add | Mul deriving (Show) 24 data Input = Input [[Operand]] [Operator] deriving (Show) 25 26 -- data Problem = Problem Operator [[Token]] 27 28 -- tokenOp :: Token -> Maybe Operator 29 -- tokenOp = \case 30 -- Op op -> Just op 31 -- _ -> Nothing 32 33 -- [[Token]] 34 -- Maybe ([[Token]], [Token]) 35 -- Maybe ([[[Token]]], [Operator]) 36 -- Maybe ([[[Token]]], [Operator]) 37 38 -- lanes :: [[Token]] -> [[[Token]]] 39 -- lanes = let x = traverse ((sequenceA . second headMay . unzip) <=< traverse unsnoc) . splitWhen (all (== Space)) . transpose in undefined 40 -- lanes = let x = fmap (uncurry zip . (splitWhen (all (== Space)) *** mapMaybe tokenOp)) . unsnoc in undefined 41 42 43 -- solve :: Problem -> Int 44 -- solve (Problem operator operands) = case operator of 45 -- Add -> sum operands 46 -- Mul -> product operands 47 48 -- part1 :: [Problem] -> Int 49 -- part1 = sum . map solve 50 51 -------------------------------------------------------------------------------- 52 -- Parsing 53 54 data ParseError = ErrorUtf8 Loc | ErrorMatrix deriving (Show) 55 instance Utf8Error ParseError where 56 utf8Error = ErrorUtf8 57 type P a = Parse ParseError a 58 59 pHws :: P ByteString 60 pHws = charWhile isSpace 61 62 pLine :: P a -> P a 63 pLine = (<* char '\n') 64 65 pToken :: P a -> P a 66 pToken = (<* pHws) 67 68 pDigit :: P Int 69 pDigit = subtract (ord '0') . ord <$> charIf isDigit 70 71 pOperand :: P Digit 72 pOperand = Digit <$> pDigit <|> Space <$ char ' ' 73 74 pOperator :: P Operator 75 pOperator = Add <$ char '+' <|> Mul <$ char '*' 76 77 pInput :: P Input 78 pInput = Input <$> many (pLine $ many pOperand) <*> 79 80 -- many pRow >>= \rs -> case M.fromList rs of 81 -- Just m -> pure m 82 -- Nothing -> err ErrorMatrix 83 84 -------------------------------------------------------------------------------- 85 -- Main 86 87 getInput :: IO [[Token]] 88 getInput = do 89 raw <- BS.getContents 90 case runParse pInput raw locZero of 91 Ok input _ _ -> pure input 92 Fail -> die "parse failure" 93 Error e -> die $ "parse error: " ++ show e 94 95 main :: IO () 96 main = do 97 input <- getInput 98 print input 99 100 -- print . part1 $ input 101 -- print . part2 $ input