109 lines
2.9 KiB
Python
109 lines
2.9 KiB
Python
|
import subprocess
|
||
|
from collections import defaultdict
|
||
|
|
||
|
|
||
|
def print_game(regs, i, insts):
|
||
|
print("\033[H\033[J", end="")
|
||
|
for j, inst in enumerate(insts):
|
||
|
start = " "
|
||
|
if j == i:
|
||
|
start = "> "
|
||
|
print(f"{start} {' '.join(inst)}")
|
||
|
for c in "abcdefgh":
|
||
|
print(c, regs[c])
|
||
|
|
||
|
|
||
|
def part_1(data):
|
||
|
regs = {c: 0 for c in "abcdefgh"}
|
||
|
insts = list(map(lambda line: line.split(), data.splitlines()))
|
||
|
|
||
|
i = 0
|
||
|
while i < len(insts):
|
||
|
inst = insts[i]
|
||
|
match inst:
|
||
|
case ["set", reg, val]:
|
||
|
regs[reg] = regs[val] if val in regs else int(val)
|
||
|
case ["sub", reg, val]:
|
||
|
regs[reg] -= regs[val] if val in regs else int(val)
|
||
|
case ["mul", reg, val]:
|
||
|
regs[reg] *= regs[val] if val in regs else int(val)
|
||
|
case ["jnz", reg, val]:
|
||
|
val = regs[val] if val in regs else int(val)
|
||
|
assert type(val) is int
|
||
|
if val != 0:
|
||
|
i += (val - 1)
|
||
|
case _:
|
||
|
assert False
|
||
|
i += 1
|
||
|
|
||
|
|
||
|
def to_c(data):
|
||
|
insts = list(map(lambda line: line.split(), data.splitlines()))
|
||
|
|
||
|
label_count = 0
|
||
|
labels = defaultdict(list)
|
||
|
for i, inst in enumerate(insts):
|
||
|
match inst:
|
||
|
case ["jnz", reg, val]:
|
||
|
label = f"label_{label_count}"
|
||
|
label_count += 1
|
||
|
inst[2] = label
|
||
|
label_i = i + int(val)
|
||
|
labels[label_i].append(label)
|
||
|
case _:
|
||
|
pass
|
||
|
|
||
|
i = 0
|
||
|
begin = ["#include <stdio.h>", "",
|
||
|
"int mul(int a, int b) {",
|
||
|
" return a * b;",
|
||
|
"}",
|
||
|
"",
|
||
|
"int main() {" ]
|
||
|
decls = " int "
|
||
|
for v in "abcdefgh":
|
||
|
decls += f"{v} = 0, "
|
||
|
decls = decls[:-2] + ";"
|
||
|
begin.append(decls)
|
||
|
body = []
|
||
|
end = [ " return 0;", "}", ]
|
||
|
|
||
|
for i, inst in enumerate(insts):
|
||
|
if i in labels:
|
||
|
for label in labels[i]:
|
||
|
body.append(label + ":")
|
||
|
match inst:
|
||
|
case ["set", reg, val]:
|
||
|
body.append(f" {reg} = {val};")
|
||
|
case ["sub", reg, val]:
|
||
|
body.append(f" {reg} -= {val};")
|
||
|
case ["mul", reg, val]:
|
||
|
body.append(f" {reg} = mul({reg}, {val});")
|
||
|
case ["jnz", reg, val]:
|
||
|
body.append(f" if ({reg} != 0) goto {val};")
|
||
|
case _:
|
||
|
assert False
|
||
|
body.append(labels[i + 1][0] + ":")
|
||
|
|
||
|
all = begin + body + end
|
||
|
with open("i23.c", "w") as f:
|
||
|
for line in all:
|
||
|
f.write(line + "\n")
|
||
|
|
||
|
def run_c():
|
||
|
subprocess.call(["gcc", "i23.c"])
|
||
|
subprocess.call(["./a.out"])
|
||
|
subprocess.call(["rm", "a.out"])
|
||
|
|
||
|
|
||
|
def main():
|
||
|
with open("i23.txt") as f:
|
||
|
data = f.read()
|
||
|
# to_c(data)
|
||
|
# part_1(data)
|
||
|
run_c()
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|