21_underflow.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 = r3 = r4 = 0
  39. while True:
  40. r3 = r4 | 65536
  41. r4 = 4332021
  42. while True:
  43. r4 = (((r4 + (r3 & 255)) & 16777215) * 65899) & 16777215
  44. if 256 > r3:
  45. break
  46. # program does this loop to divide r3 by 256:
  47. #r2 = 0
  48. #while (r2 + 1) * 256 <= r3:
  49. # r2 += 1
  50. #r3 = r2
  51. r3 //= 256
  52. #if r4 == r0:
  53. # break
  54. yield r4
  55. line = sys.stdin.readline()[:-1]
  56. ip = int(line[4:])
  57. program = list(parse_insts(sys.stdin))
  58. #numbers = run()
  59. numbers = simulate()
  60. # part 1
  61. first = next(numbers)
  62. print(first)
  63. # part 2
  64. seen = set()
  65. last = first
  66. for n in numbers:
  67. if n in seen:
  68. break
  69. seen.add(n)
  70. last = n
  71. print(last)