Solve 2018 day 19 finally
This commit is contained in:
parent
9a30c8b88d
commit
2647ccd353
109
2018/d19.py
109
2018/d19.py
@ -2,40 +2,133 @@ from lib import get_data, str_to_ints
|
||||
import d16
|
||||
|
||||
|
||||
def part_1(data):
|
||||
def print_regs(regs):
|
||||
print(" ".join([f"regs[{i}]={regs[i]:10}" for i in range(len(regs))]) + " (ip)")
|
||||
|
||||
|
||||
def print_inst(i, insts, ip):
|
||||
op, arg1, arg2, dest = insts[i]
|
||||
dest = f"regs[{dest}]" if dest != ip else "ip"
|
||||
match op:
|
||||
case "addi":
|
||||
print(f"{i:2} {dest} = regs[{arg1}] + {arg2}")
|
||||
case "addr":
|
||||
print(f"{i:2} {dest} = regs[{arg1}] + regs[{arg2}]")
|
||||
case "muli":
|
||||
print(f"{i:2} {dest} = regs[{arg1}] * {arg2}")
|
||||
case "mulr":
|
||||
print(f"{i:2} {dest} = regs[{arg1}] * regs[{arg2}]")
|
||||
case "seti":
|
||||
print(f"{i:2} {dest} = {arg1}")
|
||||
case "setr":
|
||||
print(f"{i:2} {dest} = regs[{arg1}]")
|
||||
case "eqrr":
|
||||
print(f"{i:2} {dest} = (regs[{arg1}] == regs[{arg2}]) ? 1 : 0")
|
||||
case "gtrr":
|
||||
print(f"{i:2} {dest} = (regs[{arg1}] > regs[{arg2}]) ? 1 : 0")
|
||||
case _:
|
||||
print(f"{i:2} {dest} = {op}({arg1}, {arg2})")
|
||||
|
||||
|
||||
def sum_of_divisors(n):
|
||||
total = 1
|
||||
for i in range(2, int(n**0.5) + 1):
|
||||
if n % i == 0:
|
||||
total += i
|
||||
if i != n // i: # do not count square root twice
|
||||
total += n // i
|
||||
if n != 1:
|
||||
total += n
|
||||
return total
|
||||
|
||||
|
||||
def run(data, break_after=None, reg_zero_init=0):
|
||||
ip = None
|
||||
regs = [0 for _ in range(6)]
|
||||
|
||||
regs[0] = 1 # part 2
|
||||
regs[0] = reg_zero_init
|
||||
|
||||
insts = []
|
||||
for line in data.splitlines():
|
||||
if line.startswith("#"):
|
||||
ip, = str_to_ints(line)
|
||||
(ip,) = str_to_ints(line)
|
||||
else:
|
||||
fs = line.split()
|
||||
vals = str_to_ints(line)
|
||||
insts.append([fs[0]] + vals)
|
||||
|
||||
count = 0
|
||||
assert ip is not None
|
||||
while regs[ip] < len(insts):
|
||||
if break_after is not None and count > break_after:
|
||||
break
|
||||
inst = insts[regs[ip]]
|
||||
f = getattr(d16, inst[0])
|
||||
# if inst[1:] == [3, 1, 3]:
|
||||
# regs[3] = regs[1]
|
||||
# regs[4] = regs[1]
|
||||
f(regs, *inst[1:])
|
||||
regs[ip] += 1
|
||||
print(regs, regs[-1] + 1)
|
||||
count += 1
|
||||
return regs
|
||||
|
||||
|
||||
def part_1(data):
|
||||
regs = run(data)
|
||||
print(regs[0])
|
||||
|
||||
|
||||
def part_2(data):
|
||||
regs = run(data, 10_000, 1)
|
||||
# by analysing the code we can see that the int computer counts the sum of
|
||||
# the number of divisors
|
||||
print(sum_of_divisors(regs[1]))
|
||||
|
||||
|
||||
def main():
|
||||
data = get_data(__file__)
|
||||
part_1(data)
|
||||
part_2(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
listing = """
|
||||
ip=5
|
||||
0 ip = regs[5] + 16
|
||||
1 regs[2] = 1
|
||||
2 regs[4] = 1
|
||||
3 regs[3] = regs[2] * regs[4] |
|
||||
4 regs[3] = (regs[3] == regs[1]) ? 1 : 0 |
|
||||
5 ip = regs[3] + regs[5] | jump to 7 if regs[3] == regs[1]
|
||||
6 ip = regs[5] + 1 | skip 7
|
||||
7 regs[0] = regs[2] + regs[0]
|
||||
8 regs[4] = regs[4] + 1 | regs[4] += 1
|
||||
9 regs[3] = (regs[4] > regs[1]) ? 1 : 0 |
|
||||
10 ip = regs[5] + regs[3] | jump to 12 if regs[4] > regs[1]
|
||||
11 ip = 2 | goto 3
|
||||
12 regs[2] = regs[2] + 1 | regs[2] += 1
|
||||
13 regs[3] = (regs[2] > regs[1]) ? 1 : 0 |
|
||||
14 ip = regs[3] + regs[5] | jump to 16 if regs[2] > regs[1]
|
||||
15 ip = 1 | goto 2
|
||||
16 ip = regs[5] * regs[5]
|
||||
17 regs[1] = regs[1] + 2
|
||||
18 regs[1] = regs[1] * regs[1]
|
||||
19 regs[1] = regs[5] * regs[1]
|
||||
20 regs[1] = regs[1] * 11
|
||||
21 regs[3] = regs[3] + 6
|
||||
22 regs[3] = regs[3] * regs[5]
|
||||
23 regs[3] = regs[3] + 15
|
||||
24 regs[1] = regs[1] + regs[3]
|
||||
25 ip = regs[5] + regs[0]
|
||||
26 ip = 0
|
||||
27 regs[3] = regs[5]
|
||||
28 regs[3] = regs[3] * regs[5]
|
||||
29 regs[3] = regs[5] + regs[3]
|
||||
30 regs[3] = regs[5] * regs[3]
|
||||
31 regs[3] = regs[3] * 14
|
||||
32 regs[3] = regs[3] * regs[5]
|
||||
33 regs[1] = regs[1] + regs[3]
|
||||
34 regs[0] = 0
|
||||
35 ip = 0
|
||||
|
||||
hypothesis: usm of numbers that divide the number in regs[0]
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user