Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

78 rindas
1.7KB

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