Advent of Code solutions
at main 46 lines 1.5 kB view raw
1{-# LANGUAGE ViewPatterns #-} 2import Control.Monad 3import Data.Functor 4import Data.List 5import Data.Maybe 6 7data Instruction 8 = Nop Int 9 | Acc Int 10 | Jmp Int 11 12swap :: Instruction -> Maybe Instruction 13swap (Nop i) = Just (Jmp i) 14swap (Jmp i) = Just (Nop i) 15swap _ = Nothing 16 17parse :: String -> Instruction 18parse (fmap read . stripPrefix "acc +" -> Just i) = Acc i 19parse (fmap read . stripPrefix "acc -" -> Just i) = Acc (-i) 20parse (fmap read . stripPrefix "jmp +" -> Just i) = Jmp i 21parse (fmap read . stripPrefix "jmp -" -> Just i) = Jmp (-i) 22parse (fmap read . stripPrefix "nop +" -> Just i) = Nop i 23parse (fmap read . stripPrefix "nop -" -> Just i) = Nop (-i) 24parse _ = error "invalid" 25 26exec :: Int -> [Int] -> [Instruction] -> Maybe Int 27exec i e _ | i `elem` e = Nothing 28exec i _ inst | i >= length inst = Just 0 29exec i e inst = case inst !! i of 30 Nop _ -> exec (i + 1) (i : e) inst 31 Acc n -> (n +) <$> exec (i + 1) (i : e) inst 32 Jmp n -> exec (i + n) (i : e) inst 33 34connect :: [Instruction] -> [Instruction] -> Instruction -> [Instruction] 35connect ls rs i = ls ++ (i : rs) 36 37fix :: [Instruction] -> Int 38fix inst = fromJust $ join $ find isJust $ zipWith3 try (inits (init inst)) (tails (tail inst)) (swap <$> inst) 39 where 40 try :: [Instruction] -> [Instruction] -> Maybe Instruction -> Maybe Int 41 try ls rs x = x <&> connect ls rs >>= exec 0 [] 42 43main :: IO () 44main = do 45 instructions <- fmap parse . lines <$> getContents 46 print $ fix instructions