No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

92 líneas
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. def consume(N, writes=''):
  24. return get_parameters(ns, pos, modes, N, writes, relbase)
  25. if isinstance(ns, str):
  26. ns = parse(ns)
  27. if isinstance(in_iter, int):
  28. in_iter = itertools.cycle([in_iter])
  29. pos = 0
  30. relbase = 0
  31. while True:
  32. op = ns[pos] % 100
  33. # instructions stupidly say ABC referring to parameters 3, 2, 1
  34. # we do a, b, c
  35. modes = list(str(ns[pos] // 100).zfill(3)[::-1])
  36. pos += 1
  37. if op == 1:
  38. a, b, c, pos = consume(3, 'c')
  39. ns[c] = a + b
  40. elif op == 2:
  41. a, b, c, pos = consume(3, 'c')
  42. ns[c] = a * b
  43. elif op == 3:
  44. a, pos = consume(1, 'a')
  45. ns[a] = next(in_iter)
  46. elif op == 4:
  47. a, pos = consume(1)
  48. yield a
  49. elif op == 5:
  50. a, b, pos = consume(2)
  51. if a != 0:
  52. pos = b
  53. elif op == 6:
  54. a, b, pos = consume(2)
  55. if a == 0:
  56. pos = b
  57. elif op == 7:
  58. a, b, c, pos = consume(3, 'c')
  59. ns[c] = int(a < b)
  60. elif op == 8:
  61. a, b, c, pos = consume(3, 'c')
  62. ns[c] = int(a == b)
  63. elif op == 9:
  64. a, pos = consume(1)
  65. relbase += a
  66. elif op == 99:
  67. return
  68. else:
  69. raise RuntimeError(op)