Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

95 Zeilen
2.1KB

  1. import collections
  2. import itertools
  3. import re
  4. MODES = {
  5. '0': lambda ns, x, relbase: ns[x],
  6. '1': lambda ns, x, relbase: x,
  7. '2': lambda ns, x, relbase: ns[x + relbase],
  8. '0-special': lambda ns, x, relbase: x,
  9. '2-special': lambda ns, x, relbase: x + relbase,
  10. }
  11. def get_parameters(ns, pos, modes, N, writes, relbase):
  12. for c in writes:
  13. # paradox: return immediate mode to use positionally outside
  14. modes[ord(c) - ord('a')] += '-special'
  15. yield pos + N
  16. for i in range(N):
  17. mode, x = modes[i], ns[pos + i]
  18. yield MODES[mode](ns, x, relbase)
  19. def compute(ns, in_iter):
  20. def consume(N, writes=''):
  21. return get_parameters(ns, pos, modes, N, writes, relbase)
  22. if isinstance(ns, str):
  23. ns = parse(ns)
  24. if isinstance(in_iter, int):
  25. in_iter = itertools.cycle([in_iter])
  26. pos = 0
  27. relbase = 0
  28. while True:
  29. op = ns[pos] % 100
  30. # instructions stupidly say ABC referring to parameters 3, 2, 1
  31. # we do a, b, c
  32. modes = list(str(ns[pos] // 100)[::-1] + '000')
  33. pos += 1
  34. if op == 1:
  35. pos, a, b, c = consume(3, 'c')
  36. ns[c] = a + b
  37. elif op == 2:
  38. pos, a, b, c = consume(3, 'c')
  39. ns[c] = a * b
  40. elif op == 3:
  41. pos, a = consume(1, 'a')
  42. ns[a] = next(in_iter)
  43. elif op == 4:
  44. pos, a = consume(1)
  45. yield a
  46. elif op == 5:
  47. pos, a, b = consume(2)
  48. if a != 0:
  49. pos = b
  50. elif op == 6:
  51. pos, a, b = consume(2)
  52. if a == 0:
  53. pos = b
  54. elif op == 7:
  55. pos, a, b, c = consume(3, 'c')
  56. ns[c] = int(a < b)
  57. elif op == 8:
  58. pos, a, b, c = consume(3, 'c')
  59. ns[c] = int(a == b)
  60. elif op == 9:
  61. pos, a = consume(1)
  62. relbase += a
  63. elif op == 99:
  64. return
  65. else:
  66. raise RuntimeError(op)
  67. def parse(string):
  68. ns = [int(n) for n in re.findall(r'-?\d+', string)]
  69. memory = collections.defaultdict(int)
  70. memory.update(enumerate(ns))
  71. return memory