21_underflow.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/usr/bin/env python3
  2. import sys
  3. isa = {
  4. 'addr': lambda a, b, reg: reg[a] + reg[b],
  5. 'addi': lambda a, b, reg: reg[a] + b,
  6. 'mulr': lambda a, b, reg: reg[a] * reg[b],
  7. 'muli': lambda a, b, reg: reg[a] * b,
  8. 'banr': lambda a, b, reg: reg[a] & reg[b],
  9. 'bani': lambda a, b, reg: reg[a] & b,
  10. 'borr': lambda a, b, reg: reg[a] | reg[b],
  11. 'bori': lambda a, b, reg: reg[a] | b,
  12. 'setr': lambda a, b, reg: reg[a],
  13. 'seti': lambda a, b, reg: a,
  14. 'gtir': lambda a, b, reg: int(a > reg[b]),
  15. 'gtri': lambda a, b, reg: int(reg[a] > b),
  16. 'gtrr': lambda a, b, reg: int(reg[a] > reg[b]),
  17. 'eqir': lambda a, b, reg: int(a == reg[b]),
  18. 'eqri': lambda a, b, reg: int(reg[a] == b),
  19. 'eqrr': lambda a, b, reg: int(reg[a] == reg[b]),
  20. }
  21. def parse_insts(f):
  22. for line in f:
  23. opcode, operands = line[:-1].split(' ', 1)
  24. a, b, out = map(int, operands.split())
  25. yield opcode, a, b, out
  26. def run():
  27. reg = [0, 0, 0, 0, 0, 0]
  28. while reg[ip] < len(program):
  29. opcode, a, b, out = program[reg[ip]]
  30. reg[out] = isa[opcode](a, b, reg)
  31. reg[ip] += 1
  32. if reg[ip] == 28:
  33. yield reg[4]
  34. elif reg[ip] == 17:
  35. reg[3] //= 256
  36. reg[ip] = 8
  37. def simulate():
  38. #r0 = 0
  39. r3 = r4 = 0
  40. while True:
  41. r3 = r4 | 65536
  42. r4 = 4332021
  43. while True:
  44. r4 = (((r4 + (r3 & 255)) & 16777215) * 65899) & 16777215
  45. if 256 > r3:
  46. break
  47. # program does this loop to divide r3 by 256:
  48. #r2 = 0
  49. #while (r2 + 1) * 256 <= r3:
  50. # r2 += 1
  51. #r3 = r2
  52. r3 //= 256
  53. #if r4 == r0:
  54. # break
  55. yield r4
  56. line = sys.stdin.readline()[:-1]
  57. ip = int(line[4:])
  58. program = list(parse_insts(sys.stdin))
  59. #numbers = run()
  60. numbers = simulate()
  61. # part 1
  62. first = next(numbers)
  63. print(first)
  64. # part 2
  65. seen = set()
  66. last = first
  67. for n in numbers:
  68. if n in seen:
  69. break
  70. seen.add(n)
  71. last = n
  72. print(last)