(indata: str)
| 31 | |
| 32 | @aoc.main('16') |
| 33 | def main(indata: str): |
| 34 | lines, rest = indata.split("\n\n\n\n") |
| 35 | observations = [] |
| 36 | for s in lines.split("\n\n"): |
| 37 | nums = [int(i) for i in re.findall("\d+", s)] |
| 38 | assert len(nums) == 12 |
| 39 | observations.append((nums[:4], nums[4:8], nums[8:])) |
| 40 | program = [int(i) for i in re.findall("\d+", rest)] |
| 41 | |
| 42 | p1, possible_codes = 0, [set(range(0,16)) for _ in range(0,16)] |
| 43 | for before,inst,after in observations: |
| 44 | valid = valid_opcodes(before,inst,after) |
| 45 | p1 += len(valid) >= 3 |
| 46 | for op in range(0,16): |
| 47 | if op not in valid and inst[0] in possible_codes[op]: |
| 48 | possible_codes[op].remove(inst[0]) |
| 49 | while any(len(codes) != 1 for codes in possible_codes): |
| 50 | for op in range(0,16): |
| 51 | if len(possible_codes[op]) > 1: |
| 52 | continue |
| 53 | c = list(possible_codes[op])[0] |
| 54 | for op2 in range(0,16): |
| 55 | if op2 != op and c in possible_codes[op2]: |
| 56 | possible_codes[op2].remove(c) |
| 57 | code_map = [0]*16 |
| 58 | for i,codes in enumerate(possible_codes): |
| 59 | code_map[list(codes)[0]] = i |
| 60 | |
| 61 | regs = [0,0,0,0] |
| 62 | for i in range(0,len(program)//4): |
| 63 | op,a,b,c = program[i*4:i*4+4] |
| 64 | regs = run_inst(regs,code_map[op],a,b,c) |
| 65 | return p1, regs[0] |
| 66 | |
| 67 | if __name__ == "__main__": |
| 68 | main() |
no test coverage detected