Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

90 lines
2.1KB

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