diff --git a/19/a.py b/19/a.py new file mode 100755 index 0000000..25c3be0 --- /dev/null +++ b/19/a.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python3 + + +def addr(regs, a, b, c): + # addr (add register) stores into register C the result of adding register A and register B. + regs.set(c, regs.get(a) + regs.get(b)) + + +def addi(regs, a, b, c): + # addi (add immediate) stores into register C the result of adding register A and value B. + regs.set(c, regs.get(a) + b) + + +def mulr(regs, a, b, c): + # mulr (multiply register) stores into register C the result of multiplying register A and register B. + regs.set(c, regs.get(a) * regs.get(b)) + + +def muli(regs, a, b, c): + # muli (multiply immediate) stores into register C the result of multiplying register A and value B. + regs.set(c, regs.get(a) * b) + + +def banr(regs, a, b, c): + # banr (bitwise AND register) stores into register C the result of the bitwise AND of register A and register B. + regs.set(c, regs.get(a) & regs.get(b)) + + +def bani(regs, a, b, c): + # bani (bitwise AND immediate) stores into register C the result of the bitwise AND of register A and value B. + regs.set(c, regs.get(a) & b) + + +def borr(regs, a, b, c): + # borr (bitwise OR register) stores into register C the result of the bitwise OR of register A and register B. + regs.set(c, regs.get(a) | regs.get(b)) + + +def bori(regs, a, b, c): + # bori (bitwise OR immediate) stores into register C the result of the bitwise OR of register A and value B. + regs.set(c, regs.get(a) | b) + + +def setr(regs, a, b, c): + # setr (set register) copies the contents of register A into register C. (Input B is ignored.) + regs.set(c, regs.get(a)) + + +def seti(regs, a, b, c): + # seti (set immediate) stores value A into register C. (Input B is ignored.) + regs.set(c, a) + + +def gtir(regs, a, b, c): + # gtir (greater-than immediate/register) sets register C to 1 if value A is greater than register B. + # Otherwise, register C is set to 0. + regs.set(c, 1 if a > regs.get(b) else 0) + + +def gtri(regs, a, b, c): + # gtri (greater-than register/immediate) sets register C to 1 if register A is greater than value B. + # Otherwise, register C is set to 0. + regs.set(c, 1 if regs.get(a) > b else 0) + + +def gtrr(regs, a, b, c): + # gtrr (greater-than register/register) sets register C to 1 if register A is greater than register B. + # Otherwise, register C is set to 0. + regs.set(c, 1 if regs.get(a) > regs.get(b) else 0) + + +def eqir(regs, a, b, c): + # eqir (equal immediate/register) sets register C to 1 if value A is equal to register B. + # Otherwise, register C is set to 0. + regs.set(c, 1 if a == regs.get(b) else 0) + + +def eqri(regs, a, b, c): + # eqri (equal register/immediate) sets register C to 1 if register A is equal to value B. + # Otherwise, register C is set to 0. + regs.set(c, 1 if regs.get(a) == b else 0) + + +def eqrr(regs, a, b, c): + # eqrr (equal register/register) sets register C to 1 if register A is equal to register B. + # Otherwise, register C is set to 0. + regs.set(c, 1 if regs.get(a) == regs.get(b) else 0) + + +opsfuncs = (addr, + addi, + mulr, + muli, + banr, + bani, + borr, + bori, + setr, + seti, + gtir, + gtri, + gtrr, + eqir, + eqri, + eqrr) + + +ops = {op.__name__: op for op in opsfuncs} + + +class Cpu(object): + def __init__(self, initial=None): + self.ipreg = None + self.regs = list(initial) if initial else [0] * 6 + + def get(self, num): + return self.regs[num] + + def set(self, num, value): + self.regs[num] = value + + def execute(self, instr, params): + """ + Execute an instruction and return the new instruction pointer value + """ + self.regs[self.ipreg] = self.ip + ops[instr](self, *params) + return self.regs[self.ipreg] + + +def main(): + setip = None + program = [] + with open("input.txt") as f: + setip = int(f.readline().strip().split()[-1]) + for line in f.readlines(): + instr, *params = line.strip().split() + program.append([instr] + [int(p) for p in params]) + + cpu = Cpu() + cpu.ipreg = setip + + ip = 0 + while ip < len(program): + instr = program[ip] + cpu.ip = ip + ip = cpu.execute(instr[0], instr[1:]) + ip += 1 + + print(cpu.regs[0]) + + +if __name__ == '__main__': + main() diff --git a/19/b.py b/19/b.py new file mode 100755 index 0000000..b8612d7 --- /dev/null +++ b/19/b.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + + +def main(): + number = 10551276 # from r5 in b_helper.py + ssum = 0 + for i in range(1, 10551276 + 1): + if number % i == 0: + ssum += i + + print(ssum) + +if __name__ == '__main__': + main() diff --git a/19/b_helper.py b/19/b_helper.py new file mode 100755 index 0000000..62c5c6d --- /dev/null +++ b/19/b_helper.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + + +from a import Cpu +import pdb + + +def main(): + setip = None + program = [] + with open("input.txt") as f: + setip = int(f.readline().strip().split()[-1]) + for line in f.readlines(): + instr, *params = line.strip().split() + program.append([instr] + [int(p) for p in params]) + + cpu = Cpu([1, 0, 0, 0, 0, 0]) + cpu.ipreg = setip + + ip = 0 + cycles = 0 + while ip < len(program): + instr = program[ip] + # if cycles % 1000 == 0: + cpu.ip = ip + ip = cpu.execute(instr[0], instr[1:]) + ip += 1 + cycles += 1 + + print("IP={:<2}, INSTR={:<18}, REGS={}".format(ip, str(instr), cpu.regs)) + + if cpu.regs[setip] == 10: + pdb.set_trace() + + +if __name__ == '__main__': + main() diff --git a/19/input.txt b/19/input.txt new file mode 100644 index 0000000..bf86858 --- /dev/null +++ b/19/input.txt @@ -0,0 +1,37 @@ +#ip 4 +addi 4 16 4 +seti 1 5 1 +seti 1 2 2 +mulr 1 2 3 +eqrr 3 5 3 +addr 3 4 4 +addi 4 1 4 +addr 1 0 0 +addi 2 1 2 +gtri 2 5 3 +addr 4 3 4 +seti 2 7 4 +addi 1 1 1 +gtrr 1 5 3 +addr 3 4 4 +seti 1 9 4 +mulr 4 4 4 +addi 5 2 5 +mulr 5 5 5 +mulr 4 5 5 +muli 5 11 5 +addi 3 1 3 +mulr 3 4 3 +addi 3 18 3 +addr 5 3 5 +addr 4 0 4 +seti 0 3 4 +setr 4 2 3 +mulr 3 4 3 +addr 4 3 3 +mulr 4 3 3 +muli 3 14 3 +mulr 3 4 3 +addr 5 3 5 +seti 0 4 0 +seti 0 5 4