import Data.List.Split main = do content <- getList <$> getContents let input = changeInput content 12 2 putStrLn (show (compute input input 0)) getList :: String -> [Int] getList = map read . splitOn "," changeInput :: [Int] -> Int -> Int -> [Int] changeInput (begin:_:_:input) input1 input2= [begin] ++ [input1] ++ [input2] ++ input func :: [Int] -> Int -> Int -> Int func xs x y = do let input = changeInput xs x y head (compute input input 0) compute :: [Int] -> [Int] -> Int -> [Int] compute (99:_) state index = state compute (op:x:y:z:_) state index = compute (drop newindex state) newstate newindex where sum = if op == 1 then (state !! x) + (state !! y) else (state !! x) * (state !! y) split = splitAt z state newstate = (fst split) ++ [sum] ++ (drop 1 (snd split)) newindex = index + 4 operation :: [Int] -> [Int] -> Int -> [Int] operation (1:x:y:z:_) state index = operation (drop newindex state) newstate newindex where sum = (state !! x) + (state !! y) split = splitAt z state newstate = (fst split) ++ [sum] ++ (drop 1(snd split)) newindex = index + 4 operation (2:x:y:z:_) state index = operation (drop newindex state) newstate newindex where sum = (state !! x) * (state !! y) split = splitAt z state newstate = (fst split) ++ [sum] ++ (drop 1 (snd split)) newindex = index + 4 operation (3:z:_) state index = operation (drop newindex state) newstate newindex where split = splitAt z state newstate = insert state (1) z newindex = index + 2 operation (4:z:_) state index = do putStrLn( show (state !! z )) let newindex = index + 2 operation (drop newindex state) state newindex insert :: [Int] -> Int -> Int -> [Int] insert xs value index = do let split = splitAt index xs (fst split)++ [value] ++ (drop 1 (snd split))