jangxx

Untitled

Dec 23rd, 2019
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.40 KB | None | 0 0
  1. def add(m, state, md, x, y, o):
  2.     m = store(m, state, md[2], o, load(m, state, md[0], x) + load(m, state, md[1], y))
  3.     return (state[0] + 4, state[1])
  4.  
  5. def mult(m, state, md, x, y, o):
  6.     m = store(m, state, md[2], o, load(m, state, md[0], x) * load(m, state, md[1], y))
  7.     return (state[0] + 4, state[1])
  8.  
  9. def halt(m, state, md):
  10.     return (-1, state[1])
  11.  
  12. def readint(m, state, md, x, external_input):
  13.     m = store(m, state, md[0], x, external_input)
  14.     return (state[0] + 2, state[1])
  15.  
  16. def output(m, state, md, x):
  17.     #print("out: ", load(m, md[0], x))
  18.     return ((state[0] + 2, state[1]), load(m, state, md[0], x))
  19.  
  20. def jmpt(m, state, md, a, jpa):
  21.     addr = load(m, state, md[1], jpa) if load(m, state, md[0], a) != 0 else state[0] + 3
  22.     return (addr, state[1])
  23.  
  24. def jmpf(m, state, md, a, jpa):
  25.     addr = load(m, state, md[1], jpa) if load(m, state, md[0], a) == 0 else state[0] + 3
  26.     return (addr, state[1])
  27.  
  28. def lt(m, state, md, a, b, o):
  29.     store(m, state, md[2], o, 1 if load(m, state, md[0], a) < load(m, state, md[1], b) else 0)
  30.     return (state[0] + 4, state[1])
  31.  
  32. def eq(m, state, md, a, b, o):
  33.     store(m, state, md[2], o, 1 if load(m, state, md[0], a) == load(m, state, md[1], b) else 0)
  34.     return (state[0] + 4, state[1])
  35.  
  36. def chrb(m, state, md, x):
  37.     return (state[0] + 2, state[1] + load(m, state, md[0], x))
  38.  
  39. def digits(num, length):
  40.     return list(map(lambda x: int(x), list(str(num).zfill(length))))
  41.  
  42. def load(m, state, mode, val):
  43.     if mode == 0:
  44.         # print(val in m, m)
  45.         if val in m:
  46.             # print(val)
  47.             return m[val]
  48.         else:
  49.             return 0
  50.     elif mode == 1:
  51.         return val
  52.     elif mode == 2:
  53.         if (state[1] + val) in m:
  54.             return m[state[1] + val]
  55.         else:
  56.             return 0
  57.        
  58.  
  59. def store(m, state, mode, addr, val):
  60.     if mode == 0:
  61.         m[addr] = val
  62.     elif mode == 1:
  63.         raise Exception("invalid mode")
  64.     elif mode == 2:
  65.         m[state[1] + addr] = val
  66.  
  67.     return m
  68.  
  69. def memslice(mem, fr, to):
  70.     return [ mem[i] for i in range(fr, to) ]
  71.  
  72. OPCODES = {
  73.     1: (3, add),
  74.     2: (3, mult),
  75.     3: (1, readint),
  76.     4: (1, output),
  77.     5: (2, jmpt),
  78.     6: (2, jmpf),
  79.     7: (3, lt),
  80.     8: (3, eq),
  81.     9: (1, chrb), # change relative base
  82.     99: (0, halt)
  83. }
  84.  
  85. def printOp(op, mem, state, modes, params):
  86.     paramStr = []
  87.  
  88.     for i in range(len(params)):
  89.         if modes[i] == 0:
  90.             md = "i"
  91.         elif modes[i] == 1:
  92.             md = ""
  93.         elif modes[i] == 2:
  94.             md = "r"
  95.  
  96.         dbgVal = ""
  97.  
  98.         if modes[i] == 0 or modes[i] == 2:
  99.             try:
  100.                 val = load(mem, state, modes[i], params[i])
  101.             except:
  102.                 val = "<none>"
  103.             dbgVal = "~({})".format(val)
  104.  
  105.         paramStr.append("{}:{}{}".format(md, params[i], dbgVal))
  106.  
  107.     if op == 1:
  108.         opStr = "add"
  109.     elif op == 2:
  110.         opStr = "mult"
  111.     elif op == 3:
  112.         opStr = "read"
  113.     elif op == 4:
  114.         opStr = "outp"
  115.     elif op == 5:
  116.         opStr = "jmpt"
  117.     elif op == 6:
  118.         opStr = "jmpf"
  119.     elif op == 7:
  120.         opStr = "lt"
  121.     elif op == 8:
  122.         opStr = "eq"
  123.     elif op == 9:
  124.         opStr = "chrb"
  125.     elif op == 99:
  126.         opStr = "halt"
  127.  
  128.     print("{} ({})".format(opStr, ", ".join(paramStr)))
  129.  
  130. def defaultInputFn():
  131.     return int(input("Enter integer: "))
  132.  
  133. def runIntcode(initial_memory, mem_parameters=[], input_parameters=[], ret="output"):
  134.     mem = { i: val for i, val in enumerate(initial_memory) }
  135.     output_values = []
  136.  
  137.     # for i,v in enumerate(initial_memory):
  138.     #     print("{:3d}: {}".format(i, v))
  139.  
  140.     ip = 0
  141.     rb = 0 # relative base
  142.  
  143.     state = (ip, rb)
  144.  
  145.     for (addr, val) in mem_parameters:
  146.         mem[addr] = val
  147.  
  148.     while True:
  149.         ip, rb = state
  150.  
  151.         op_full = mem[ip]
  152.  
  153.         op = op_full % 100
  154.  
  155.         length, fn = OPCODES[op]
  156.         modes = list(reversed(digits(op_full, length+2)[:-2]))
  157.  
  158.         # print(op, modes, mem[ip+1:ip+1+length])
  159.         # printOp(op, modes, memslice(mem, ip+1, ip+1+length))
  160.  
  161.         if op == 3:
  162.             if len(input_parameters) > 0:
  163.                 state = fn(mem, state, modes, *memslice(mem, ip+1, ip+1+length), input_parameters.pop(0))
  164.             else:
  165.                 state = fn(mem, state, modes, *memslice(mem, ip+1, ip+1+length), int(input("Enter integer: ")))
  166.         elif op == 4:
  167.             state, output = fn(mem, state, modes, *memslice(mem, ip+1, ip+1+length))
  168.             output_values.append(output)
  169.         else:
  170.             state = fn(mem, state, modes, *memslice(mem, ip+1, ip+1+length))
  171.  
  172.         if state[0] == -1:
  173.             break
  174.  
  175.     if ret == "output":
  176.         return output_values
  177.     elif ret == "mem0":
  178.         return mem[0]
  179.  
  180. def runIntcodeGen(initial_memory, input_queue=list(), mem_parameters=[], input_generator=None, input_fn=defaultInputFn, print_inputs=False, print_input_ascii=False, always_yield=False ):
  181.     mem = { i: val for i, val in enumerate(initial_memory) }
  182.  
  183.     ip = 0
  184.     rb = 0 # relative base
  185.  
  186.     state = (ip, rb)
  187.  
  188.     for (addr, val) in mem_parameters:
  189.         mem[addr] = val
  190.  
  191.     while True:
  192.         ip, rb = state
  193.  
  194.         op_full = mem[ip]
  195.  
  196.         op = op_full % 100
  197.  
  198.         length, fn = OPCODES[op]
  199.         modes = list(reversed(digits(op_full, length+2)[:-2]))
  200.  
  201.         # print(op, modes, memslice(mem, ip+1, ip+1+length))
  202.         # printOp(op, mem, state, modes, memslice(mem, ip+1, ip+1+length))
  203.  
  204.         if op == 99:
  205.             print("HALT CALLED")
  206.  
  207.         if op == 3:
  208.             if input_generator is not None:
  209.                 in_val = next(input_generator)
  210.             elif len(input_queue) > 0:
  211.                 in_val = input_queue.pop(0)
  212.             else:
  213.                 in_val = input_fn()
  214.  
  215.             if print_inputs:
  216.                 print(chr(in_val) if print_input_ascii else in_val, end="")
  217.  
  218.             state = fn(mem, state, modes, *memslice(mem, ip+1, ip+1+length), in_val)
  219.  
  220.             if always_yield:
  221.                 yield None
  222.         elif op == 4:
  223.             state, output = fn(mem, state, modes, *memslice(mem, ip+1, ip+1+length))
  224.             yield output
  225.         else:
  226.             state = fn(mem, state, modes, *memslice(mem, ip+1, ip+1+length))
  227.             if always_yield:
  228.                 yield None
  229.  
  230.         if state[0] == -1:
  231.             break
Add Comment
Please, Sign In to add comment