The struggled with a counting solution for a long time. I submitted with a simple enumerative solution in the end but managed to get it right after some pause time:
Haskell
Fast to Run, Stepwise Solution
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OrPatterns #-}
module Main (main) where
import Control.Monad ( (<$!>) )
import qualified Data.List as List
main :: IO ()
main = do
rotations <- (fmap parseRotation . init . lines) <$!> getContents
print $ part1 rotations
print $ part2 rotations
part2 :: [Either Int Int] -> Int
part2 rotations = let
foldRotation (position, zeroCount) operation = case operation of
Left y -> let
(zeroPasses, y') = y `divMod` 100
position' = (position - y') `mod` 100
zeroCount' = zeroPasses + zeroCount + if position <= y' then fromEnum $ position /= 0 else 0
in (position', zeroCount')
Right y -> let
(zeroPasses, y') = y `divMod` 100
position' = (position + y') `mod` 100
zeroCount' = zeroPasses + zeroCount + if y' + position >= 100 then 1 else 0
in (position', zeroCount')
in snd $ List.foldl' foldRotation (50, 0) rotations
part1 :: [Either Int Int] -> Int
part1 rotations = let
positions = List.scanl applyRotation 50 rotations
in List.length . filter (== 0) $ positions
applyRotation :: Int -> Either Int Int -> Int
applyRotation x = \case
Left y -> (x - y) `mod` 100
Right y -> (x + y) `mod` 100
parseRotation :: String -> Either Int Int
parseRotation = \case
'R':rest -> Right $ read rest
'L':rest -> Left $ read rest
bad -> error $ "invalid rotation operation: " ++ bad
Fast to Code, Exhaustively Enumerating Solution
-- | Old solution enumerating all the numbers
part2' :: [Either Int Int] -> Int
part2' rotations = let
intermediatePositions _ [] = []
intermediatePositions x (op:ops) = case op of
Left 0; Right 0 -> intermediatePositions x ops
Left y -> let x' = pred x `mod` 100 in x' : intermediatePositions x' (Left (pred y) : ops)
Right y -> let x' = succ x `mod` 100 in x' : intermediatePositions x' (Right (pred y) : ops)
in List.length . List.filter (== 0) . intermediatePositions 50 $ rotations