intcode.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. from operator import add, mul, lt, eq
  2. def read_program(f):
  3. return list(map(int, f.readline().split(',')))
  4. def run(p, get_input, memsize=0):
  5. def decode_param(offset):
  6. return p[pc + offset], modes // (10 ** (offset - 1)) % 10
  7. def pload(offset):
  8. param, mode = decode_param(offset)
  9. return param if mode == 1 else p[param + relbase * mode // 2]
  10. def pstore(offset, value):
  11. param, mode = decode_param(offset)
  12. p[param + relbase * mode // 2] = value
  13. opmap = {1: add, 2: mul, 7: lt, 8: eq}
  14. p = p + [0] * memsize
  15. pc = relbase = 0
  16. while p[pc] != 99:
  17. modes, opcode = divmod(p[pc], 100)
  18. if opcode in (1, 2, 7, 8):
  19. pstore(3, opmap[opcode](pload(1), pload(2)))
  20. pc += 4
  21. elif opcode == 3:
  22. pstore(1, get_input())
  23. pc += 2
  24. elif opcode == 4:
  25. yield pload(1)
  26. pc += 2
  27. elif opcode == 5:
  28. pc = pload(2) if pload(1) else pc + 3
  29. elif opcode == 6:
  30. pc = pload(2) if not pload(1) else pc + 3
  31. elif opcode == 9:
  32. relbase += pload(1)
  33. pc += 2
  34. def run_iter(p, memsize=0):
  35. def decode_param(offset):
  36. return p[pc + offset], modes // (10 ** (offset - 1)) % 10
  37. def pload(offset):
  38. param, mode = decode_param(offset)
  39. return param if mode == 1 else p[param + relbase * mode // 2]
  40. def pstore(offset, value):
  41. param, mode = decode_param(offset)
  42. p[param + relbase * mode // 2] = value
  43. opmap = {1: add, 2: mul, 7: lt, 8: eq}
  44. p = p + [0] * memsize
  45. pc = relbase = 0
  46. while p[pc] != 99:
  47. modes, opcode = divmod(p[pc], 100)
  48. if opcode in (1, 2, 7, 8):
  49. pstore(3, opmap[opcode](pload(1), pload(2)))
  50. pc += 4
  51. elif opcode == 3:
  52. inp = (yield)
  53. #print('inp', inp)
  54. pstore(1, inp)
  55. pc += 2
  56. elif opcode == 4:
  57. outp = pload(1)
  58. #print('outp', outp)
  59. yield outp
  60. pc += 2
  61. elif opcode == 5:
  62. pc = pload(2) if pload(1) else pc + 3
  63. elif opcode == 6:
  64. pc = pload(2) if not pload(1) else pc + 3
  65. elif opcode == 9:
  66. relbase += pload(1)
  67. pc += 2