Main.hs (1508B)
1 module Main (main) where 2 3 import Control.Applicative 4 import Data.ByteString qualified as BS 5 import Data.Functor 6 import Sparsec 7 import System.Exit (die) 8 9 -------------------------------------------------------------------------------- 10 -- Solution 11 12 data Rotation = L Int | R Int deriving (Show) 13 14 rotate :: Int -> Rotation -> Int 15 rotate n = \case 16 L i -> (n - i) `mod` 100 17 R i -> (n + i) `mod` 100 18 19 part1 :: [Rotation] -> Int 20 part1 = length . filter (== 0) . scanl rotate 50 21 22 expand :: Rotation -> [Rotation] 23 expand = \case 24 L i -> replicate i (L 1) 25 R i -> replicate i (R 1) 26 27 part2 :: [Rotation] -> Int 28 part2 = part1 . (>>= expand) 29 30 -------------------------------------------------------------------------------- 31 -- Parsing 32 33 newtype ParseError = ErrorUtf8 Loc deriving (Show) 34 instance Utf8Error ParseError where 35 utf8Error = ErrorUtf8 36 type P a = Parse ParseError a 37 38 pInt :: P Int 39 pInt = fromIntegral <$> natural 10 40 41 pRotation :: P Rotation 42 pRotation = (char 'L' $> L <|> char 'R' $> R) <*> pInt 43 44 pRotations :: P [Rotation] 45 pRotations = many (pRotation <* char '\n') <* eof 46 47 -------------------------------------------------------------------------------- 48 -- Main 49 50 getInput :: IO [Rotation] 51 getInput = do 52 raw <- BS.getContents 53 case runParse pRotations raw locZero of 54 Ok rots _ _ -> pure rots 55 Fail -> die "parse failure" 56 Error e -> die $ "parse error: " ++ show e 57 58 main :: IO () 59 main = do 60 input <- getInput 61 print . part1 $ input 62 print . part2 $ input