solve.py (3388B)
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 37 38def solve1(args): 39 global register, insptr 40 while register[inspaddr] < len(instructs): 41 insptr = register[inspaddr] 42 ins = instructs[insptr] 43 #aoc.debug(register) 44 45 # execute command 46 if len(register) <= ins[3]: 47 register += [0 for x in range(ins[3] - len(register) + 1)] 48 register[ins[3]] = opmap[ins[0]](ins[1], ins[2]) 49 50 # increment instruction pointer 51 register[inspaddr] += 1 52 53 return register[0] 54 55 56alpha = [chr(c + ord('a')) for c in range(26)] 57 58dismap = dict() 59dismap["addr"] = lambda a, b : "%s + %s" % (alpha[a], alpha[b]) 60dismap["addi"] = lambda a, b : "%s + %d" % (alpha[a], b) 61dismap["mulr"] = lambda a, b : "%s * %s" % (alpha[a], alpha[b]) 62dismap["muli"] = lambda a, b : "%s * %d" % (alpha[a], b) 63dismap["banr"] = lambda a, b : str(alpha[a] & alpha[b]) 64dismap["bani"] = lambda a, b : str(alpha[a] & b) 65dismap["borr"] = lambda a, b : str(alpha[a] | alpha[b]) 66dismap["bori"] = lambda a, b : str(alpha[a] | b) 67dismap["setr"] = lambda a, b : str(alpha[a]) 68dismap["seti"] = lambda a, b : str(a) 69dismap["gtir"] = lambda a, b : "(%d > %s)" % (a, alpha[b]) 70dismap["gtri"] = lambda a, b : "(%s > %d)" % (alpha[a], b) 71dismap["gtrr"] = lambda a, b : "(%s > %s)" % (alpha[a], alpha[b]) 72dismap["eqir"] = lambda a, b : "(%d == %s)" % (a, alpha[b]) 73dismap["eqri"] = lambda a, b : "(%s == %d)" % (alpha[a], b) 74dismap["eqrr"] = lambda a, b : "(%s == %s)" % (alpha[a], alpha[b]) 75 76def disassemble(): 77 for i in range(len(instructs)): 78 ins = instructs[i] 79 aoc.debug(i ,":",alpha[ins[3]],"=", dismap[ins[0]](ins[1], ins[2])) 80 aoc.debug() 81 82""" divisor sum algo disassembled 83c = 1 84b = 1 85a = 0 86while b <= f: 87 c = 1 88 while c <= f: 89 if b * c == f: 90 a += b 91 c += 1 92 b += 1 93""" 94 95def solve2(args): 96 f = 10551276 # found by running 97 98 res = 0 99 sqrtf = sqrt(f) 100 for i in range(1, int(sqrtf)): 101 if f % i == 0: 102 res += i + f / i 103 104 if int(sqrtf) % f == 0: 105 res += sqrtf 106 107 return int(res) 108 109aoc.run(solve1, solve2, sols=[2072, 27578880])