Browse Source

Messy day 18

master
Chris Smith 6 years ago
parent
commit
a69a905753
2 changed files with 154 additions and 0 deletions
  1. 113
    0
      18.py
  2. 41
    0
      data/18.txt

+ 113
- 0
18.py View File

@@ -0,0 +1,113 @@
1
+from collections import defaultdict
2
+
3
+get_value = lambda registers, operand: registers[operand] if operand in registers else int(operand)
4
+
5
+def handle_snd(pc, registers, state, args):
6
+    state['snd'].append(get_value(registers, args[0]))
7
+    state['sndc'] += 1
8
+    return pc + 1
9
+
10
+def handle_set(pc, registers, state, args):
11
+    registers[args[0]] = get_value(registers, args[1])
12
+    return pc + 1
13
+
14
+def handle_add(pc, registers, state, args):
15
+    registers[args[0]] += get_value(registers, args[1])
16
+    return pc + 1
17
+
18
+def handle_mul(pc, registers, state, args):
19
+    registers[args[0]] *= get_value(registers, args[1])
20
+    return pc + 1
21
+
22
+def handle_mod(pc, registers, state, args):
23
+    registers[args[0]] %= get_value(registers, args[1])
24
+    return pc + 1
25
+
26
+def handle_jgz(pc, registers, state, args):
27
+    return pc + get_value(registers, args[1]) if get_value(registers, args[0]) > 0 else pc + 1
28
+
29
+def handle_rcv_p1(pc, registers, state, args):
30
+    if get_value(registers, args[0]) != 0:
31
+        state['recovered'].append(state['snd'][-1])
32
+    return pc + 1
33
+
34
+def handle_rcv_p2(pc, registers, state, args):
35
+    if len(state['rcv']) > 0:
36
+        registers[args[0]] = state['rcv'].pop(0)
37
+        return pc + 1
38
+    else:
39
+        return pc
40
+
41
+def process_p1(instructions):
42
+    pc, state, registers = 0, {'snd': [], 'sndc': 0, 'recovered': []}, defaultdict(lambda: 0)
43
+    ops = {
44
+        'snd': handle_snd,
45
+        'set': handle_set,
46
+        'add': handle_add,
47
+        'mul': handle_mul,
48
+        'mod': handle_mod,
49
+        'jgz': handle_jgz,
50
+        'rcv': handle_rcv_p1,
51
+    }
52
+    while len(state['recovered']) == 0:
53
+        ins = instructions[pc]
54
+        pc = ops[ins[0]](pc, registers, state, ins[1:])
55
+    return state['recovered'][0]
56
+
57
+
58
+def can_execute(programs):
59
+    for p in programs:
60
+        if p['state']['terminated']:
61
+            yield False
62
+        elif p['state']['waiting'] and len(p['state']['rcv']) == 0:
63
+            yield False
64
+        else:
65
+            yield True
66
+
67
+
68
+def process_p2(instructions):
69
+    p1_to_p2, p2_to_p1 = [], []
70
+    programs = [{
71
+        'pc': 0,
72
+        'state': {'snd': p1_to_p2, 'sndc': 0, 'rcv': p2_to_p1, 'terminated': False, 'waiting': False},
73
+        'regs': defaultdict(lambda: 0)
74
+    }, {
75
+        'pc': 0,
76
+        'state': {'snd': p2_to_p1, 'sndc': 0, 'rcv': p1_to_p2, 'terminated': False, 'waiting': False},
77
+        'regs': defaultdict(lambda: 0),
78
+    }]
79
+    programs[1]['regs']['p'] = 1
80
+
81
+    ops = {
82
+        'snd': handle_snd,
83
+        'set': handle_set,
84
+        'add': handle_add,
85
+        'mul': handle_mul,
86
+        'mod': handle_mod,
87
+        'jgz': handle_jgz,
88
+        'rcv': handle_rcv_p2,
89
+    }
90
+
91
+    p = 0
92
+    while any(can_execute(programs)):
93
+        for _ in range(1000):
94
+            pc = programs[p]['pc']
95
+            programs[p]['state']['waiting'] = False
96
+            if pc < 0 or pc >= len(instructions):
97
+                programs[p]['state']['terminated'] = True
98
+                break
99
+            ins = instructions[pc]
100
+            programs[p]['pc'] = ops[ins[0]](pc, programs[p]['regs'], programs[p]['state'], ins[1:])
101
+            if programs[p]['pc'] == pc:
102
+                programs[p]['state']['waiting'] = True
103
+                break
104
+        p = 1 - p
105
+
106
+    return programs[1]['state']['sndc']
107
+
108
+
109
+
110
+with open('data/18.txt', 'r') as file:
111
+    input = list(map(str.split, file.readlines()))
112
+    print(f'Part one: {process_p1(input)}')
113
+    print(f'Part two: {process_p2(input)}')

+ 41
- 0
data/18.txt View File

@@ -0,0 +1,41 @@
1
+set i 31
2
+set a 1
3
+mul p 17
4
+jgz p p
5
+mul a 2
6
+add i -1
7
+jgz i -2
8
+add a -1
9
+set i 127
10
+set p 680
11
+mul p 8505
12
+mod p a
13
+mul p 129749
14
+add p 12345
15
+mod p a
16
+set b p
17
+mod b 10000
18
+snd b
19
+add i -1
20
+jgz i -9
21
+jgz a 3
22
+rcv b
23
+jgz b -1
24
+set f 0
25
+set i 126
26
+rcv a
27
+rcv b
28
+set p a
29
+mul p -1
30
+add p b
31
+jgz p 4
32
+snd a
33
+set a b
34
+jgz 1 3
35
+snd b
36
+set f 1
37
+add i -1
38
+jgz i -11
39
+snd a
40
+jgz f -16
41
+jgz a -19

Loading…
Cancel
Save