Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Data.List
- type Program = ([String], [String], Int, Int, [Int])
- replace :: [a] -> [a] -> Int -> a -> [a]
- replace lst infTail index str =
- if index < (length lst)
- then (take index lst) ++ [str] ++ (drop (index + 1) lst)
- else
- replace (lst ++ infTail) infTail index str
- getValue :: String -> Int
- getValue str = if (head str) == '#' then read (tail str) else 0
- firstOutermostBracketAndComplement :: String -> (String, String)
- firstOutermostBracketAndComplement str = ((takeWhile ('[' ==) str) ++ (takeWhile (']' /=) (dropWhile ('[' ==) str)) ++ (map (\x -> ']') [1..depth]), (dropWhile (']' ==) (dropWhile (']' /=) str)))
- where depth = length (takeWhile ('[' ==) str)
- separateFirstInstruction :: String -> (String, String)
- separateFirstInstruction str
- |elem c "io._$>^v" = ([c], tail str)
- |c == '[' = firstOutermostBracketAndComplement str
- |c == '{' = (str, "")
- |elem c "#+-" = ([c] ++ takeWhile (\x -> elem x "0123456789") (tail str), dropWhile (\x -> elem x "0123456789") (tail str))
- where c = head str
- splitIntoInstructions' :: String -> [String]
- splitIntoInstructions' str
- |str == "" = []
- |otherwise = [inst] ++ (splitIntoInstructions' rest) --map (\x -> "_") [0..]
- where (inst, rest) = separateFirstInstruction str
- splitIntoInstructions :: String -> [String]
- splitIntoInstructions str = if notElem '{' str then splitIntoInstructions' (str ++ "{_}") else splitIntoInstructions' str
- setUpProgram :: [String] -> Program
- setUpProgram lst = if start == [] then ((init lst), infiniteTail, 0, 0, []) else ((init lst), infiniteTail, 0, (\(Just x) -> x) (elemIndex (head start) lst), [])
- where start = filter (\x -> (head x) == '*') lst
- infiniteTail = splitIntoInstructions' (tail (init (last lst)))
- performStep :: Program -> Program
- performStep (source, infiniteTail, value, location, out)
- |s == "_" = (source, infiniteTail, value, location + 1, out)
- |s == "$" = (source, infiniteTail, location, location + 1, out)
- |s == ">" = (source, infiniteTail, value, value, out)
- |s == "^" = (source, infiniteTail, getValue (source !! value), location + 1, out)
- |head s == '+' = (source, infiniteTail, value + (read (tail s)), location + 1, out)
- |head s == '-' = (source, infiniteTail, value - (read (tail s)), location + 1, out)
- |head s == '#' = (source, infiniteTail, read (tail s), location + 1, out)
- |head s == '[' = (replace source infiniteTail value (init (tail s)), infiniteTail, value, location + 1, out)
- |s == "v" = (replace source infiniteTail location ("#" ++ (show value)), infiniteTail, value, location + 1, out)
- |s == "o" = (source, infiniteTail, value, location + 1, out ++ [value])
- where s = source !! location
- runProgram :: Program -> [Int] -> [Int]
- runProgram (source, infiniteTail, value, location, out) inp
- |location >= (length source) - 1 = runProgram (source ++ infiniteTail, infiniteTail, value, location, out) inp
- |source !! location == "." = out
- |source !! location == "i" = runProgram (source, infiniteTail, head inp, location + 1, out) (tail inp)
- |otherwise = runProgram (performStep (source, infiniteTail, value, location, out)) inp
- -- where s = source !! location
- executeProgram :: String -> [Int] -> [Int]
- executeProgram src inp = runProgram (setUpProgram (splitIntoInstructions src)) inp
- executeProgramNoInput :: String -> [Int]
- executeProgramNoInput src = executeProgram src []
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement