Advertisement
Guest User

Untitled

a guest
Dec 6th, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import           Data.List.Split (splitOn)
  2. import           Data.Vector     (Vector, fromList, (!), (//))
  3.  
  4. operations = [(+), (*)]
  5.  
  6. parseOpcode :: Int -> [Int]
  7. parseOpcode 0    = []
  8. parseOpcode code = [mod code 10] ++ parseOpcode (code `div` 10)
  9.  
  10. executeMemory :: Vector Int -> Int -> IO (Maybe (Vector Int))
  11. executeMemory memory ip = do
  12.   case (opcode !! 0) of
  13.     1 -> addOrMul
  14.     2 -> addOrMul
  15.     3 -> input -- Would like to use `in` here, but thats a reserved keyword in Haskell
  16.     4 -> out
  17.     5 -> jnz
  18.     6 -> jz
  19.     7 -> cmpLT
  20.     8 -> eq
  21.     9 ->
  22.       if ((length opcode > 1) && (opcode !! 1) == 9)
  23.         then return $ Just memory
  24.         else return Nothing
  25.     _ -> return Nothing
  26.   where
  27.     opcode = parseOpcode $ memory ! ip
  28.     op = operations !! ((opcode !! 0) - 1)
  29.     addOrMul =
  30.       let addr1 = memory ! (ip + 1)
  31.           addr2 = memory ! (ip + 2)
  32.           addr3 = memory ! (ip + 3)
  33.           param1 =
  34.             if (length opcode > 2 && opcode !! 2 == 1)
  35.               then addr1
  36.               else memory ! addr1
  37.           param2 =
  38.             if (length opcode > 3 && opcode !! 3 == 1)
  39.               then addr2
  40.               else memory ! addr2
  41.           result = op param1 param2
  42.        in executeMemory (memory // [(addr3, result)]) (ip + 4)
  43.     input =
  44.       let addr1 = memory ! (ip + 1)
  45.        in do putStr "INPUT>> "
  46.              input <- getLine
  47.              executeMemory
  48.                (memory // [(addr1, (read :: String -> Int) input)])
  49.                (ip + 2)
  50.     out =
  51.       let addr1 = memory ! (ip + 1)
  52.        in do putStrLn $
  53.                (++) "OUTPUT>> " $
  54.                show $
  55.                if (length opcode > 2 && opcode !! 2 == 1)
  56.                  then addr1
  57.                  else memory ! addr1
  58.              executeMemory memory (ip + 2)
  59.     jnz =
  60.       let addr1 = memory ! (ip + 1) -- Zero flag
  61.           addr2 = memory ! (ip + 2) -- New IP position
  62.           param1 =
  63.             if (length opcode > 2 && opcode !! 2 == 1)
  64.               then addr1
  65.               else memory ! addr1
  66.           param2 =
  67.             if (length opcode > 3 && opcode !! 3 == 1)
  68.               then addr2
  69.               else memory ! addr2
  70.           newIP =
  71.             if (param1 /= 0)
  72.               then param2
  73.               else (ip + 3)
  74.        in executeMemory memory newIP
  75.     jz =
  76.       let addr1 = memory ! (ip + 1) -- Zero flag
  77.           addr2 = memory ! (ip + 2) -- New IP position
  78.           param1 =
  79.             if (length opcode > 2 && opcode !! 2 == 1)
  80.               then addr1
  81.               else memory ! addr1
  82.           param2 =
  83.             if (length opcode > 3 && opcode !! 3 == 1)
  84.               then addr2
  85.               else memory ! addr2
  86.           newIP =
  87.             if (param1 == 0)
  88.               then param2
  89.               else (ip + 3)
  90.        in executeMemory memory newIP
  91.     cmpLT =
  92.       let addr1 = memory ! (ip + 1)
  93.           addr2 = memory ! (ip + 2)
  94.           addr3 = memory ! (ip + 3)
  95.           param1 =
  96.             if (length opcode > 2 && opcode !! 2 == 1)
  97.               then addr1
  98.               else memory ! addr1
  99.           param2 =
  100.             if (length opcode > 3 && opcode !! 3 == 1)
  101.               then addr2
  102.               else memory ! addr2
  103.           modMem =
  104.             if (param1 < param2)
  105.               then memory // [(addr3, 1)]
  106.               else memory // [(addr3, 0)]
  107.        in executeMemory modMem (ip + 4)
  108.     eq =
  109.       let addr1 = memory ! (ip + 1)
  110.           addr2 = memory ! (ip + 2)
  111.           addr3 = memory ! (ip + 3)
  112.           param1 =
  113.             if (length opcode > 2 && opcode !! 2 == 1)
  114.               then addr1
  115.               else memory ! addr1
  116.           param2 =
  117.             if (length opcode > 3 && opcode !! 3 == 1)
  118.               then addr2
  119.               else memory ! addr2
  120.           modMem =
  121.             if (param1 == param2)
  122.               then memory // [(addr3, 1)]
  123.               else memory // [(addr3, 0)]
  124.        in executeMemory modMem (ip + 4)
  125.  
  126. main :: IO ()
  127. main = do
  128.   input <-
  129.     map (read :: String -> Int) <$> splitOn "," <$> readFile "day5input.txt"
  130.   let memory = fromList input
  131.   result <- executeMemory memory 0
  132.   putStrLn "DUMP MEMORY (Y/N)?"
  133.   putStr "INPUT>> "
  134.   dumpMem <- getLine
  135.   case dumpMem of
  136.     "Y" -> putStrLn $ show result
  137.     _   -> return ()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement