George Thomas be0a6510d8 Use lazy text for test outputs
Simplifies encoding code slightly, and potentially saves a lot of time for failing tests. Plus we've always been using `T.show` in practice anyway, so it's an easy change to make.
2025-12-04 21:24:49 +00:00

59 lines
1.7 KiB
Haskell

module Puzzles.Day1 (puzzle) where
import Control.Monad.State
import Data.Bifunctor
import Data.Functor
import Data.Text.Lazy qualified as TL
import Puzzle
import Text.Megaparsec hiding (Pos)
import Text.Megaparsec.Char
import Text.Megaparsec.Char.Lexer qualified as Lex
puzzle :: Puzzle
puzzle =
Puzzle
{ number = 1
, parser = flip sepEndBy newline $ (,) <$> ((char 'L' $> L) <|> (char 'R' $> R)) <*> (Inc <$> Lex.decimal)
, parts =
[ TL.show
. sum
. flip evalState 50
. traverse \(d, i) -> do
modify $ snd . step i d
p' <- get
pure $ Count if p' == 0 then 1 else 0
, TL.show
. sum
. flip evalState 50
. traverse \(d, i) -> do
p <- get
c <- state $ step i d
p' <- get
pure case d of
R -> abs c
L ->
if
| p == 0 -> abs c - 1
| p' == 0 -> abs c + 1
| otherwise -> abs c
]
, extraTests = mempty
}
data Direction = L | R
deriving (Eq, Ord, Show)
newtype Pos = Pos Int
deriving newtype (Eq, Ord, Show, Num)
newtype Inc = Inc Int
deriving newtype (Eq, Ord, Show, Num)
newtype Count = Count Int
deriving newtype (Eq, Ord, Show, Num)
step :: Inc -> Direction -> Pos -> (Count, Pos)
step (Inc i) d (Pos p) = bimap Count Pos case d of
L -> (p - i) `divMod` 100
R -> (p + i) `divMod` 100