Advertisement
alexandrajay2002

Advent of Code 2024 day 17 part 2

Dec 17th, 2024 (edited)
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.18 KB | Source Code | 0 0
  1. from sys import argv
  2.  
  3.  
  4. def parse_register(line):
  5.     index = line.find(':') + 2
  6.     end_index = index + 1
  7.     while end_index <= len(line) and line[index:end_index].isdigit():
  8.         end_index += 1
  9.  
  10.     return int(line[index:end_index])
  11.  
  12.  
  13. def parse_program(line):
  14.     index = line.find(':') + 2
  15.     return [int(x) for x in line[index:].split(',')]
  16.  
  17.  
  18. def parse(src):
  19.     _, program = src.split('\n\n', 1)
  20.     program = parse_program(program)
  21.     return program
  22.  
  23.  
  24. def get_register(a, b, c, opcode):
  25.     if opcode <= 3:  # assume the opcode is in bounds
  26.         return opcode
  27.     elif opcode == 4:
  28.         return a
  29.     elif opcode == 5:
  30.         return b
  31.     else:
  32.         return c
  33.  
  34.  
  35. def test(a, program, end, out_index):
  36.     b = c = 0
  37.     pc = 0
  38.     while pc < end:
  39.         instruction, opcode = program[pc:pc+2]
  40.         match instruction:
  41.             case 0:
  42.                 a = a >> get_register(a, b, c, opcode)
  43.  
  44.             case 1:
  45.                 b ^= opcode
  46.  
  47.             case 2:
  48.                 b = get_register(a, b, c, opcode) % 8
  49.  
  50.             case 3:
  51.                 if a != 0:
  52.                     pc = opcode
  53.                     continue
  54.  
  55.             case 4:
  56.                 b ^= c
  57.  
  58.             case 5:
  59.                 output = get_register(a, b, c, opcode) % 8
  60.                 if output != program[out_index]:
  61.                     return False
  62.                 out_index += 1
  63.  
  64.             case 6:
  65.                 b = a >> get_register(a, b, c, opcode)
  66.  
  67.             case 7:
  68.                 c = a >> get_register(a, b, c, opcode)
  69.  
  70.         pc += 2
  71.  
  72.     return out_index == end
  73.  
  74.  
  75. def main(program):
  76.     end = len(program)
  77.  
  78.     # 0 gets the initial 0 and no more
  79.     in_progress = [(0, len(program) - 1)]
  80.     while len(in_progress) > 0:
  81.         a, distance = in_progress.pop(0)
  82.         for chunk in range(8):
  83.             next_a = (a << 3) + chunk
  84.  
  85.             if not test(next_a, program, end, distance):
  86.                 continue
  87.  
  88.             if distance == 0:
  89.                 return next_a
  90.  
  91.             in_progress.append((next_a, distance - 1))
  92.  
  93.     return None
  94.  
  95.  
  96. if __name__ == '__main__':
  97.     print(main(parse(open(argv[1]).read())))
  98.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement