repl.it
@pyelias/

AOC2019-5

Python

No description

fork
loading
Files
  • main.py
  • inp.py
  • inp.txt
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import inp as inp

class IntCode():
    def __init__(self, mem, inp, out):
        self.mem = mem
        self.inp_cb = inp
        self.out_cb = out

        self.pc = 0
        self.mode = 0 # dont like putting instruction-specific state here
        self.done = False
    
    def read_next(self):
        res = self.mem[self.pc]
        self.pc += 1
        return res
    
    def get_mode(self):
        self.modes, res = divmod(self.modes, 10)
        return res

    def get_arg(self):
        mode = self.get_mode()
        if mode == 0:
            return self.mem[self.read_next()]
        elif mode == 1:
            return self.read_next()
    
    def get_pos(self):
        mode = self.get_mode()
        if mode == 0:
            return self.read_next()
        elif mode == 1:
            raise ValueError("input to immediate")

    def run_one(self):
        instr = self.read_next()
        self.modes, opcode = divmod(instr, 100)
        self.instrs[opcode](self)
    
    def run(self):
        while not self.done:
            self.run_one()
    
    def add(self):
        a, b, dest = self.get_arg(), self.get_arg(), self.get_pos()
        self.mem[dest] = a + b
    
    def mul(self):
        a, b, dest = self.get_arg(), self.get_arg(), self.get_pos()
        self.mem[dest] = a * b

    def inp(self):
        self.mem[self.get_pos()] = self.inp_cb()
    
    def out(self):
        self.out_cb(self.get_arg())
    
    def jmp_true(self):
        cond, pos = self.get_arg(), self.get_arg()
        if cond:
            self.pc = pos
    
    def jmp_false(self):
        cond, pos = self.get_arg(), self.get_arg()
        if not cond:
            self.pc = pos
    
    def lt(self):
        a, b, dest = self.get_arg(), self.get_arg(), self.get_pos()
        self.mem[dest] = int(a < b)
    
    def eq(self):
        a, b, dest = self.get_arg(), self.get_arg(), self.get_pos()
        self.mem[dest] = int(a == b)
    
    def finish(self):
        self.done = True
    
    instrs = {
        1: add,
        2: mul,
        3: inp,
        4: out,
        5: jmp_true,
        6: jmp_false,
        7: lt,
        8: eq,
        99: finish,
    }

c = IntCode(inp.CODE, lambda: 5, print)
c.run()
?