You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

79 lines
2.0 KiB

#!/usr/bin/env python3
import sys, re, math
out = []
def output(i):
out.append(i)
def instr(opc, op, ra, rb, rc, p):
cop = op
if op in [4,5,6]: cop = [ra,rb,rc][op-4]
if op == 7: cop = 'ERROR'
if opc == 0: # 'adv' instruction
ra = math.trunc(ra / 2**cop)
p += 2
elif opc == 1: # 'bxl' instruction
rb = rb ^ op
p += 2
elif opc == 2: # 'bst' instruction
rb = cop % 8
p += 2
elif opc == 3: # 'jnz' instruction
if ra != 0:
p = op
else:
p += 2
elif opc == 4: # 'bxc' instruction
rb = rb ^ rc
p += 2
elif opc == 5: # 'out' instruction
output(cop % 8)
p += 2
elif opc == 6: # 'bdv' instruction
rb = math.trunc(ra / 2**cop)
p += 2
elif opc == 7: # 'cdv' instruction
rc = math.trunc(ra / 2**cop)
p += 2
return ra, rb, rc, p
def step(lb, ub, i, exp):
for ra in range(lb, ub):
if (((ra//8**i)%8) ^ 1 ^ int((ra//8**i) / 2**((ra//8** i%8)^2)) % 8) == exp: yield ra
if __name__ == '__main__':
ins = open(sys.argv[1]).read()
g = re.search(r'Register A: (?P<ra>\d+)\nRegister B: (?P<rb>\d+)\nRegister C: (?P<rc>\d+)\n\nProgram: (?P<prog>(\d+,?)*)', ins)
ra, rb, rc = int(g['ra']), int(g['rb']), int(g['rc'])
prog = [int(p) for p in g['prog'].split(',')]
pointer = 0
while True:
if pointer >= len(prog): break
ra, rb, rc, pointer = instr(prog[pointer], prog[pointer+1], ra, rb, rc, pointer)
possible_bounds = [(0,8)]
for i in range(15,-1,-1):
exp = prog[i]
possible_x = []
for lb, ub in possible_bounds:
possible_x += [i for i in step(lb, ub, 0, exp)]
possible_bounds = [(x*8,(x+1)*8) for x in possible_x]
ra = min(possible_x)
# challenge 1
res1 = ','.join([str(o) for o in out])
print(f"challenge 1:\n{res1}\n")
# challenge 2
res2 = ra
print(f"challenge 2 (only works for my input):\n{res2}")