aoc2025

Advent of Code 2025
git clone git://git.rr3.xyz/aoc2025
Log | Files | Refs | Submodules

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