Advertisement
Guest User

Intcode Computer

a guest
Dec 9th, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Julia 4.12 KB | None | 0 0
  1. module Intcode
  2.  
  3. using OffsetArrays
  4.  
  5. export parseInput, Program, runProgram, newProgram
  6.  
  7. const parseInput(i) = split(i, ",") |>
  8.     lines -> map(x -> parse(Int, x), lines) |>
  9.     x -> OffsetArray(x, -1)
  10.  
  11. mutable struct Program
  12.     memory :: OffsetArrays.OffsetArray{Int64,1,Array{Int64,1}}
  13.     address :: Int
  14.     input :: Array{Int, 1}
  15.     output :: Array{Int, 1}
  16.     relativeBase :: Int
  17.     halted :: Bool
  18.     paused :: Bool
  19.     stopOnOutput :: Bool
  20. end
  21.  
  22. function parseOpcode(opcode::Int)
  23.     if opcode <= 10 || opcode == 99
  24.         return (opcode, (0, 0, 0))
  25.     end
  26.  
  27.     digs = digits(opcode; pad = 5)
  28.  
  29.     if [digs[1], digs[2]] == [9,9]
  30.         return (99, (digs[3], digs[4], digs[5]))
  31.     end
  32.  
  33.     return (digs[1], (digs[3], digs[4], digs[5]))
  34. end
  35.  
  36. function accessMemory(program::Program, address::Int)
  37.     diff = address-length(program.memory)+1
  38.  
  39.     if diff <= 0
  40.         return program.memory[address]
  41.     else
  42.         resize!(parent(program.memory), length(program.memory)+(diff))
  43.         return 0
  44.     end
  45. end
  46.  
  47. function applyMode(program::Program, mode::Int, value::Int, output=false)
  48.     if mode == 0
  49.         return !output ? accessMemory(program, value) : value
  50.     elseif mode == 1
  51.         return value
  52.     elseif mode == 2
  53.         return !output ? accessMemory(program, value+program.relativeBase) : value+program.relativeBase
  54.     end
  55. end
  56.  
  57. function parseInstructions(program::Program, opcode::Int, modes::Tuple{Int, Int, Int})
  58.     if opcode == 99
  59.         return (0, 0, 0)
  60.     elseif opcode == 3
  61.         return (0, 0, applyMode(program, modes[1], program.memory[program.address+1], true))
  62.     elseif opcode in [4, 9]
  63.         return (applyMode(program, modes[1], program.memory[program.address+1], false), 0, 0)
  64.     else
  65.         return map(((i, mode),) -> applyMode(program, mode, program.memory[program.address+i], i == 3), enumerate(modes))
  66.     end
  67. end
  68.  
  69. const operations  = Dict(
  70.     1 => (program, input, output) -> begin
  71.         program.memory[output] = input[1] + input[2]
  72.         program.address += 4
  73.     end,
  74.     2 => (program, input, output) -> begin
  75.         program.memory[output] = input[1] * input[2]
  76.         program.address += 4
  77.     end,
  78.     3 => (program, input, output) -> begin
  79.         program.memory[output] = popfirst!(program.input)
  80.         program.address += 2
  81.     end,
  82.     4 => (program, input, output) -> begin
  83.         push!(program.output, input[1])
  84.         program.address += 2
  85.        
  86.         if program.stopOnOutput
  87.             program.paused == true
  88.         end
  89.     end,
  90.     5 => (program, input, output) -> begin
  91.         program.address = input[1] != 0 ? input[2] : program.address + 3
  92.     end,
  93.     6 => (program, input, output) -> begin
  94.         program.address = input[1] == 0 ? input[2] : program.address + 3
  95.     end,
  96.     7 => (program, input, output) -> begin
  97.         program.memory[output] = input[1] < input[2] ? 1 : 0
  98.         program.address += 4
  99.     end,
  100.     8 => (program, input, output) -> begin
  101.         program.memory[output] = input[1] == input[2] ? 1 : 0
  102.         program.address += 4
  103.     end,
  104.     9 => (program, input, output) -> begin
  105.         program.relativeBase += input[1]
  106.         program.address += 2
  107.     end,
  108.     99 => (program, input, output) -> program.halted = true
  109. )
  110.  
  111. function doOperation(program::Program)
  112.     memoryValue = accessMemory(program, program.address)
  113.     opcode, modes = parseOpcode(memoryValue)
  114.  
  115.     instructions = parseInstructions(program, opcode, modes)
  116.     input = instructions[1:2]
  117.     outputAddress = instructions[end]
  118.  
  119.     accessMemory(program, outputAddress)
  120.  
  121.     #println("#", program.address, " " ,opcode, " ", modes, " ", memoryValue, " ", (instructions[1], instructions[2])  , " ", isnothing(outputAddress) ? 0 : outputAddress)
  122.  
  123.     operations[opcode](program, input, outputAddress)
  124. end
  125.  
  126. const runProgram(program::Program) = begin
  127.     while !program.halted
  128.         doOperation(program)
  129.     end
  130. end
  131.  
  132. function newProgram(str, input, index=0, output=[], relativeBase=0, stopOnOutput=false)
  133.     Program(parseInput(str), index, input, output, relativeBase, false, false, stopOnOutput)
  134. end
  135.  
  136. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement