Advertisement
SansPapyrus683

stuff

Oct 16th, 2022
2,495
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 2.52 KB | Source Code | 0 0
  1. module Intcode (interp) where
  2.  
  3. import Debug.Trace
  4. import Data.Char
  5.  
  6. data Mode = Pos | Imm deriving (Eq, Ord, Enum, Show)
  7. data Op = Op { o :: Int, aTypes :: [Mode] } deriving (Eq, Show)
  8.  
  9. upd :: [a] -> Int -> a -> [a]
  10. upd l pos n = take pos l ++ [n] ++ drop (pos + 1) l
  11.  
  12. argNum :: Int -> Int
  13. argNum op
  14.     | op == 1 || op == 2 || op == 7 || op == 8 = 3
  15.     | op == 3 || op == 4 = 1
  16.     | op == 5 || op == 6 = 2
  17.     | op == 99 = 0
  18.  
  19. parseArg :: Int -> Op
  20. parseArg op =
  21.     let
  22.         o = op `mod` 100
  23.         aNum = argNum o
  24.         given = show (op `div` 100)
  25.         numToMode x
  26.             | x == 0 = Pos
  27.             | x == 1 = Imm
  28.  
  29.         hid :: [Mode] = replicate (aNum - length given) Pos
  30.  
  31.         args = hid ++ map (numToMode . digitToInt) given
  32.     in Op o (reverse args)
  33.  
  34. get :: [Int] -> Int -> Mode -> Int
  35. get code arg Pos = code !! (code !! arg)
  36. get code arg Imm = code !! arg
  37.  
  38. interp :: [Int] -> Int -> IO([Int], Int)
  39. interp code at =
  40.     let Op opType argTypes = parseArg (code !! at)
  41.         nextInd = at + argNum opType + 1
  42.         args = [get code (at + i) (argTypes !! (i - 1)) | i <- [1..length argTypes]]
  43.     in case opType of
  44.         1 -> let
  45.                 val1 = args !! 0
  46.                 val2 = args !! 1
  47.                 ind = code !! (at + 3)
  48.             in interp (upd code ind (val1 + val2)) nextInd
  49.        
  50.         2 -> let
  51.                 val1 = args !! 0
  52.                 val2 = args !! 1
  53.                 ind = code !! (at + 3)
  54.             in interp (upd code ind (val1 * val2)) nextInd
  55.        
  56.         3 -> do
  57.             val <- readLn
  58.             let ind = code !! (at + 1)
  59.             interp (upd code ind val) nextInd
  60.        
  61.         4 -> do
  62.             print (args !! 0)
  63.             interp code nextInd
  64.        
  65.         5 -> let
  66.                 jump = args !! 0 /= 0
  67.                 goTo = args !! 1
  68.             in interp code (if jump then goTo else nextInd)
  69.        
  70.         6 -> let
  71.                 jump = args !! 0 == 0
  72.                 goTo = args !! 1
  73.             in interp code (if jump then goTo else nextInd)
  74.        
  75.         7 -> let
  76.                 store = if args !! 0 < args !! 1 then 1 else 0
  77.                 ind = code !! (at + 3)
  78.             in interp (upd code ind store) nextInd
  79.        
  80.         8 -> let
  81.                 store = if args !! 0 == args !! 1 then 1 else 0
  82.                 ind = code !! (at + 3)
  83.             in interp (upd code ind store) nextInd
  84.        
  85.         99 -> pure (code, at)
  86.        
  87.         _ -> do pure ([], -1)
  88.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement