solve.py (3864B)
1import sys 2sys.path.append("../common") 3import aoc 4from math import sqrt 5 6def parse_command(l): 7 s = l.split(" ") 8 args = [s[0]] 9 args = args + [int(v) for v in s[1:]] 10 return args 11 12data = aoc.data.split("\n") 13 14inspaddr = int(data[0][4:]) 15instructs = [parse_command(l) for l in data[1:] if len(l) != 0] 16 17register = [0 for x in range(inspaddr+1)] 18 19opmap = dict() 20opmap["addr"] = lambda a, b : register[a] + register[b] 21opmap["addi"] = lambda a, b : register[a] + b 22opmap["mulr"] = lambda a, b : register[a] * register[b] 23opmap["muli"] = lambda a, b : register[a] * b 24opmap["banr"] = lambda a, b : register[a] & register[b] 25opmap["bani"] = lambda a, b : register[a] & b 26opmap["borr"] = lambda a, b : register[a] | register[b] 27opmap["bori"] = lambda a, b : register[a] | b 28opmap["setr"] = lambda a, b : register[a] 29opmap["seti"] = lambda a, b : a 30opmap["gtir"] = lambda a, b : 1 * (a > register[b]) 31opmap["gtri"] = lambda a, b : 1 * (register[a] > b) 32opmap["gtrr"] = lambda a, b : 1 * (register[a] > register[b]) 33opmap["eqir"] = lambda a, b : 1 * (a == register[b]) 34opmap["eqri"] = lambda a, b : 1 * (register[a] == b) 35opmap["eqrr"] = lambda a, b : 1 * (register[a] == register[b]) 36 37def varname(v): 38 return "R"+str(v) 39 40dismap = dict() 41dismap["addr"] = lambda a, b : "%s + %s" % (varname(a), varname(b)) 42dismap["addi"] = lambda a, b : "%s + %d" % (varname(a), b) 43dismap["mulr"] = lambda a, b : "%s * %s" % (varname(a), varname(b)) 44dismap["muli"] = lambda a, b : "%s * %d" % (varname(a), b) 45dismap["banr"] = lambda a, b : "%s & %s" % (varname(a), varname(b)) 46dismap["bani"] = lambda a, b : "%s & %d" % (varname(a), b) 47dismap["borr"] = lambda a, b : "%s | %s" % (varname(a), varname(b)) 48dismap["bori"] = lambda a, b : "%s | %d" % (varname(a), b) 49dismap["setr"] = lambda a, b : "%s" % (varname(a)) 50dismap["seti"] = lambda a, b : "%d" % (a) 51dismap["gtir"] = lambda a, b : "(%d > %s)" % (a, varname(b)) 52dismap["gtri"] = lambda a, b : "(%s > %d)" % (varname(a), b) 53dismap["gtrr"] = lambda a, b : "(%s > %s)" % (varname(a), varname(b)) 54dismap["eqir"] = lambda a, b : "(%d == %s)" % (a, varname(b)) 55dismap["eqri"] = lambda a, b : "(%s == %d)" % (varname(a), b) 56dismap["eqrr"] = lambda a, b : "(%s == %s)" % (varname(a), varname(b)) 57 58def disassemble(s, e): 59 for i in range(s, e): 60 ins = instructs[i] 61 aoc.debug(i ,":",varname(ins[3]),"=", dismap[ins[0]](ins[1], ins[2])) 62 aoc.debug() 63 64def execute(): 65 global register, insptr 66 67 while register[inspaddr] < len(instructs): 68 insptr = register[inspaddr] 69 ins = instructs[insptr] 70 71 # execute command 72 if len(register) <= ins[3]: 73 register += [0 for x in range(ins[3] - len(register) + 1)] 74 register[ins[3]] = opmap[ins[0]](ins[1], ins[2]) 75 76 # part 1 77 #if insptr == 13 and register[4] == 1: 78 # aoc.debug(register) 79 # return 80 81 # increment instruction pointer 82 register[inspaddr] += 1 83 84def solve1(args): 85 r0 = 1797184 # (first opportunity for comparison r1 and r0) 86 87 #disassemble(0, len(instructs)) 88 #execute() 89 90 return r0 91 92def solve2(args): 93 r1 = 0 94 candidates = list() 95 while True: 96 r4 = r1 | 65536 # flip 9th bit 97 r1 = 3798839 98 while True: # scan bytes of r4 and add them to r1 and multiply 99 r5 = r4 & 255 100 r1 += r5 101 r1 = r1 & 16777215 102 r1 *= 65899 # equals 1 00000001 01101011 103 r1 = r1 & 16777215 104 if r4 < 256: 105 break 106 r4 = int(r4/256) # bit shift 8 to the right 107 if r1 not in candidates: 108 candidates.append(r1) 109 elif r1 == candidates[-1]: 110 return candidates[-1] 111 112aoc.run(solve1, solve2, sols=[1797184, 11011493])