-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path8a.hs
46 lines (37 loc) · 1.25 KB
/
8a.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
{-# LANGUAGE OverloadedStrings #-}
import Data.Either
import Data.List
import Data.List.Index
import qualified Data.Map as M
import Text.Parsec hiding (count)
import Prelude
main = do
input <- getContents
putStr $ show $ fn input
data Action = Nop | Acc Int | Jump Int | Done deriving (Show)
intP :: Parsec String () Int
intP = read <$> (plus <|> minus <|> number)
where
plus = char '+' *> number
minus = (:) <$> char '-' <*> number
number = many1 digit
actionPG :: String -> (Int -> Action) -> Parsec String () Action
actionPG x t = do
try $ string x
space
t <$> intP
instructionP :: Parsec String () Action
instructionP =
actionPG "nop" (const Nop)
<|> actionPG "acc" Acc
<|> actionPG "jmp" Jump
setDone :: Maybe Action -> Maybe Action
setDone _ = Just Done
runInstructions :: Int -> Int -> M.Map Int Action -> Int
runInstructions acc idx map = case M.lookup idx map of
Nothing -> acc
Just Done -> acc
Just (Acc x) -> runInstructions (acc + x) (idx + 1) (M.alter setDone idx map)
Just (Jump x) -> runInstructions acc (idx + x) (M.alter setDone idx map)
Just Nop -> runInstructions acc (idx + 1) (M.alter setDone idx map)
fn xs = runInstructions 0 0 $ M.fromList $ indexed $ rights $ map (runParser instructionP () "") $ lines xs