-
Notifications
You must be signed in to change notification settings - Fork 1
/
sol_09.aes
148 lines (138 loc) · 7.63 KB
/
sol_09.aes
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
@compiler >= 4.2.0
include "List.aes"
contract Day9 =
entrypoint solve_1() = run(code(), [1])
entrypoint solve_2() = run(code(), [2])
function run(code : list(int), input : list(int)) =
run'(0, setup_mem(code), 0, input, [])
entrypoint run'(pc : int, mem : map(int, int), rel : int, input : list(int), output : list(int)) =
let opcode = mem[pc]
let op = opcode mod 100
let i0 = (opcode / 100) mod 10
let i1 = (opcode / 1000) mod 10
let i2 = (opcode / 10000) mod 10
switch(op)
99 => List.reverse(output)
1 => // Add
let x = val(pc + 1, i0, mem, rel)
let y = val(pc + 2, i1, mem, rel)
let z = ptr(pc + 3, i2, mem, rel)
run'(pc + 4, mem{[z] = x + y}, rel, input, output)
2 => // Mul
let x = val(pc + 1, i0, mem, rel)
let y = val(pc + 2, i1, mem, rel)
let z = ptr(pc + 3, i2, mem, rel)
run'(pc + 4, mem{[z] = x * y}, rel, input, output)
3 => // Input
let z = ptr(pc + 1, i0, mem, rel)
switch(input)
in :: input => run'(pc + 2, mem{[z] = in}, rel, input, output)
[] => abort(String.concat("Program ran out of input at: ", Int.to_str(pc)))
4 => // Output
let x = val(pc + 1, i0, mem, rel)
run'(pc + 2, mem, rel, input, x :: output)
5 => // Jump if non-zero
let x = val(pc + 1, i0, mem, rel)
let y = val(pc + 2, i1, mem, rel)
run'(if(x != 0) y else pc + 3, mem, rel, input, output)
6 => // Jump if zero
let x = val(pc + 1, i0, mem, rel)
let y = val(pc + 2, i1, mem, rel)
run'(if(x == 0) y else pc + 3, mem, rel, input, output)
7 => // Less than
let x = val(pc + 1, i0, mem, rel)
let y = val(pc + 2, i1, mem, rel)
let z = ptr(pc + 3, i2, mem, rel)
run'(pc + 4, mem{[z] = if(x < y) 1 else 0}, rel, input, output)
8 => // Equals
let x = val(pc + 1, i0, mem, rel)
let y = val(pc + 2, i1, mem, rel)
let z = ptr(pc + 3, i2, mem, rel)
run'(pc + 4, mem{[z] = if(x == y) 1 else 0}, rel, input, output)
9 =>
let x = val(pc + 1, i0, mem, rel)
run'(pc + 2, mem, rel + x, input, output)
_ =>
abort(String.concat("Bad opcode: ", Int.to_str(opcode)))
function
ptr : (int, int, map(int, int), int) => int
ptr(ix, 0, mem, _) = mem[ix]
ptr(ix, 1, _, _) = ix
ptr(ix, 2, mem, rel) = rel + mem[ix]
function
val : (int, int, map(int, int), int) => int
val(ix, 0, mem, _) = mem[mem[ix] = 0]
val(ix, 1, mem, _) = mem[ix]
val(ix, 2, mem, rel) = mem[rel + mem[ix] = 0]
function setup_mem(is : list(int)) =
setup_mem'(0, is, {})
function
setup_mem' : (int, list(int), map(int, int)) => map(int, int)
setup_mem'(_, [], m) = m
setup_mem'(ix, x :: xs, m) = setup_mem'(ix + 1, xs, m{[ix] = x})
// function code0() =
// [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99]
// function code1() =
// [1102,34915192,34915192,7,4,7,99,0]
// function code2() =
// [104,1125899906842624,99]
function code() =
[1102, 34463338, 34463338, 63, 1007, 63, 34463338, 63, 1005, 63, 53, 1101,
3, 0, 1000, 109, 988, 209, 12, 9, 1000, 209, 6, 209, 3, 203, 0, 1008, 1000,
1, 63, 1005, 63, 65, 1008, 1000, 2, 63, 1005, 63, 904, 1008, 1000, 0, 63,
1005, 63, 58, 4, 25, 104, 0, 99, 4, 0, 104, 0, 99, 4, 17, 104, 0, 99, 0, 0,
1102, 35, 1, 1010, 1102, 1, 33, 1013, 1101, 0, 715, 1022, 1102, 1, 20,
1004, 1102, 1, 24, 1012, 1101, 36, 0, 1005, 1101, 0, 655, 1024, 1102, 32,
1, 1014, 1101, 0, 499, 1026, 1102, 1, 242, 1029, 1101, 0, 25, 1002, 1101,
0, 27, 1017, 1101, 708, 0, 1023, 1101, 0, 21, 1016, 1101, 0, 28, 1000,
1101, 0, 492, 1027, 1102, 34, 1, 1015, 1102, 29, 1, 1007, 1102, 247, 1,
1028, 1101, 0, 39, 1011, 1102, 1, 31, 1018, 1102, 1, 0, 1020, 1102, 1, 37,
1006, 1101, 1, 0, 1021, 1102, 26, 1, 1009, 1102, 1, 38, 1008, 1101, 30, 0,
1019, 1102, 1, 23, 1001, 1102, 650, 1, 1025, 1101, 22, 0, 1003, 109, 7,
2101, 0, -7, 63, 1008, 63, 29, 63, 1005, 63, 205, 1001, 64, 1, 64, 1105, 1,
207, 4, 187, 1002, 64, 2, 64, 109, -1, 1202, -1, 1, 63, 1008, 63, 35, 63,
1005, 63, 227, 1106, 0, 233, 4, 213, 1001, 64, 1, 64, 1002, 64, 2, 64, 109,
17, 2106, 0, 5, 4, 239, 1105, 1, 251, 1001, 64, 1, 64, 1002, 64, 2, 64,
109, -1, 21108, 40, 39, -4, 1005, 1018, 271, 1001, 64, 1, 64, 1106, 0, 273,
4, 257, 1002, 64, 2, 64, 109, -9, 1206, 8, 285, 1106, 0, 291, 4, 279, 1001,
64, 1, 64, 1002, 64, 2, 64, 109, -13, 2108, 27, 0, 63, 1005, 63, 307, 1106,
0, 313, 4, 297, 1001, 64, 1, 64, 1002, 64, 2, 64, 109, 11, 2101, 0, -5, 63,
1008, 63, 37, 63, 1005, 63, 339, 4, 319, 1001, 64, 1, 64, 1105, 1, 339,
1002, 64, 2, 64, 109, 13, 21101, 41, 0, -9, 1008, 1015, 41, 63, 1005, 63,
365, 4, 345, 1001, 64, 1, 64, 1106, 0, 365, 1002, 64, 2, 64, 109, -14,
1201, -6, 0, 63, 1008, 63, 22, 63, 1005, 63, 385, 1106, 0, 391, 4, 371,
1001, 64, 1, 64, 1002, 64, 2, 64, 109, -10, 1202, 3, 1, 63, 1008, 63, 22,
63, 1005, 63, 417, 4, 397, 1001, 64, 1, 64, 1105, 1, 417, 1002, 64, 2, 64,
109, 6, 1207, -3, 21, 63, 1005, 63, 437, 1001, 64, 1, 64, 1105, 1, 439, 4,
423, 1002, 64, 2, 64, 109, 16, 21107, 42, 41, -8, 1005, 1014, 455, 1105, 1,
461, 4, 445, 1001, 64, 1, 64, 1002, 64, 2, 64, 109, -28, 2107, 24, 7, 63,
1005, 63, 481, 1001, 64, 1, 64, 1106, 0, 483, 4, 467, 1002, 64, 2, 64, 109,
33, 2106, 0, 0, 1001, 64, 1, 64, 1106, 0, 501, 4, 489, 1002, 64, 2, 64,
109, -18, 2108, 38, -1, 63, 1005, 63, 519, 4, 507, 1105, 1, 523, 1001, 64,
1, 64, 1002, 64, 2, 64, 109, -3, 1208, -4, 25, 63, 1005, 63, 545, 4, 529,
1001, 64, 1, 64, 1106, 0, 545, 1002, 64, 2, 64, 109, 12, 21102, 43, 1, -8,
1008, 1010, 43, 63, 1005, 63, 571, 4, 551, 1001, 64, 1, 64, 1106, 0, 571,
1002, 64, 2, 64, 109, -1, 1207, -8, 27, 63, 1005, 63, 593, 4, 577, 1001,
64, 1, 64, 1106, 0, 593, 1002, 64, 2, 64, 109, -7, 21101, 44, 0, 8, 1008,
1018, 42, 63, 1005, 63, 617, 1001, 64, 1, 64, 1105, 1, 619, 4, 599, 1002,
64, 2, 64, 109, -4, 1208, -1, 39, 63, 1005, 63, 639, 1001, 64, 1, 64, 1105,
1, 641, 4, 625, 1002, 64, 2, 64, 109, 13, 2105, 1, 5, 4, 647, 1106, 0, 659,
1001, 64, 1, 64, 1002, 64, 2, 64, 109, 4, 1206, -3, 673, 4, 665, 1106, 0,
677, 1001, 64, 1, 64, 1002, 64, 2, 64, 109, -22, 21108, 45, 45, 10, 1005,
1011, 699, 4, 683, 1001, 64, 1, 64, 1105, 1, 699, 1002, 64, 2, 64, 109, 29,
2105, 1, -7, 1001, 64, 1, 64, 1105, 1, 717, 4, 705, 1002, 64, 2, 64, 109,
-19, 21107, 46, 47, 5, 1005, 1016, 739, 4, 723, 1001, 64, 1, 64, 1106, 0,
739, 1002, 64, 2, 64, 109, -8, 2102, 1, 2, 63, 1008, 63, 33, 63, 1005, 63,
763, 1001, 64, 1, 64, 1106, 0, 765, 4, 745, 1002, 64, 2, 64, 109, 1, 1201,
-2, 0, 63, 1008, 63, 25, 63, 1005, 63, 791, 4, 771, 1001, 64, 1, 64, 1105,
1, 791, 1002, 64, 2, 64, 109, 16, 1205, 0, 803, 1105, 1, 809, 4, 797, 1001,
64, 1, 64, 1002, 64, 2, 64, 109, -8, 1205, 9, 827, 4, 815, 1001, 64, 1, 64,
1106, 0, 827, 1002, 64, 2, 64, 109, -4, 2102, 1, -3, 63, 1008, 63, 36, 63,
1005, 63, 853, 4, 833, 1001, 64, 1, 64, 1106, 0, 853, 1002, 64, 2, 64, 109,
17, 21102, 47, 1, -6, 1008, 1019, 50, 63, 1005, 63, 877, 1001, 64, 1, 64,
1105, 1, 879, 4, 859, 1002, 64, 2, 64, 109, -29, 2107, 22, 5, 63, 1005, 63,
897, 4, 885, 1106, 0, 901, 1001, 64, 1, 64, 4, 64, 99, 21102, 27, 1, 1,
21101, 0, 915, 0, 1106, 0, 922, 21201, 1, 25338, 1, 204, 1, 99, 109, 3,
1207, -2, 3, 63, 1005, 63, 964, 21201, -2, -1, 1, 21101, 942, 0, 0, 1105,
1, 922, 22102, 1, 1, -1, 21201, -2, -3, 1, 21102, 957, 1, 0, 1106, 0, 922,
22201, 1, -1, -2, 1105, 1, 968, 21202, -2, 1, -2, 109, -3, 2106, 0, 0]