day 24 optimize
[aoc_eblake.git] / 2017 / day10.m4
bloba77f9cd61e89f6222e824e5502d94d9eb876a296
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day10.input] day10.m4
3 # Optionally use -Dalgo=array|stack|pack to experiment with implementation.
5 include(`common.m4')ifelse(common(10), `ok', `',
6 `errprint(`Missing common initialization
7 ')m4exit(1)')
9 ifdef(`algo', `', `define(`algo', `array')')
11 define(`input', translit((include(defn(`file'))), `,()'nl, `_'))
12 define(`prep', `define(`A$1', $1)')
13 define(`reset', `forloop_arg(0, 255, `prep')define(`p', 0)define(`s', 0)')
14 define(`swap', `_$0(`A$1', A$1, `A$2', A$2)')
15 define(`_swap', `define(`$1', $4)define(`$3', $2)')
16 define(`round', `ifelse(`$1', `', `', `_$0($1, p)define(`p',
17   eval((p+$1+s)&255))define(`s', incr(s))$0(shift($@))')')
18 define(`_round', `ifelse($1, 0, `', $1, 1, `', `swap($2,
19   eval(($1+$2-1)&255))$0(decr(decr($1)), ifelse($2, 255, 0, `incr($2)'))')')
20 reset()
21 round(translit(defn(`input'), `_', `,'))
22 define(`part1', eval(A0*A1))
24 define(`set', `define(`V$1', eval($1 + $2))')
25 forloop(0, 9, `set(', `, 48)')
26 define(`V_', 44)
27 define(`split', `ifelse(`$1', `', ``17,31,73,47,23'', `defn(`V'substr(`$1',
28   0, 1))`,'$0(substr(`$1', 1))')')
29 define(`list', split(defn(`input')))
31 ifelse(defn(`algo'), `array', `
32 output(1, `Using per-element array swaps')
33 reset()
34 forloop(0, 63, `round(list)')
35 define(`dense', `eval(0forloop(eval($1*16), eval($1*16+15), `^defn(`A'', `)'),
36   16, 2)')
37 define(`part2', forloop_arg(0, 15, `dense'))
39 ', defn(`algo'), `stack', `
40 output(1, `Using stack one element at a time')
41 define(`head', `l0')
42 define(`_rd', `head`'popdef(defn(`head'))')
43 pushdef(`l0', `popdef(`l0')define(`head', `l1')head()')
44 forloop_rev(255, 0, `pushdef(`l0',',`)')
45 define(`rv1', `pushdef(`l$1', _rd)')
46 define(`prep', `define(`rv'incr($1), `pushdef(`l$2$3', _rd)rv$1(`$2$3')')')
47 forloop(1, 254, `prep(', `, `$', 1)')
48 define(`sk0')
49 define(`prep', `define(`sk'incr($1), `pushdef(`t$2$3', _rd)sk$1(`$2$3')')')
50 forloop(0, 254, `prep(', `, `$', 1)')
52 define(`p', 0)define(`s', 0)
53 define(`sk', `sk$1(`$2')pushdef(`t$2', `popdef(`l$2')define(`head',
54   `l'incr(`$2'))head()')define(`s', `$2')')
55 define(`rnd', `ifelse(`$1',,, `define(`p',eval((p+$1+s)&255))_$0($1,
56   incr(s))$0(shift($@))')')
57 define(`_rnd', `pushdef(`l$2', `popdef(`l$2')stack_reverse(`t$2',
58   `l$2')head()')rv$1(`$2')sk(eval(s&255), `$2')')
59 forloop(0, 63, `rnd(list)')
60 define(`last', `pushdef(`l$1', `popdef(`l$1')stack_reverse(`t$1',
61   `l$1')head()')rv1($1)sk(eval(255-p), $1)')
62 last(incr(s))
63 define(`dense', `eval(0forloop_arg(0, 15, `^_rd'), 16, 2)')
64 define(`part2', forloop_arg(0, 15, `dense'))
66 ', defn(`algo'), `pack', `
67 output(1, `Using packed stack')
68 pushdef(`l0', `0(,1)')
69 define(`prep', `pushdef(`l0', 8(0forloop(eval($1*8), eval($1*8+7),
70   `,')))')
71 forloop_rev(31, 0, `prep(', `)')
72 define(`C', `0')
73 define(`prep', `define(`rv$1',
74   `pushdef(`l$2$3', swap$1(`$2$3', _rd(`$1', l$2$4)))')')
75 forloop(1, 8, `prep(', `, `$', 1, 2)')
76 define(`prep', `define(`rv$1', `rv8($2@)rv'eval($1-8)`(`$2$3',C)')')
77 forloop(9, 255, `prep(', `, `$', 1)')
78 define(`swap1', ``1(`$1',`$2')'')
79 define(`swap2', ``2(`$1',`$3',`$2')'')
80 define(`swap3', ``3(`$1',`$4',`$3',`$2')'')
81 define(`swap4', ``4(`$1',`$5',`$4',`$3',`$2')'')
82 define(`swap5', ``5(`$1',`$6',`$5',`$4',`$3',`$2')'')
83 define(`swap6', ``6(`$1',`$7',`$6',`$5',`$4',`$3',`$2')'')
84 define(`swap7', ``7(`$1',`$8',`$7',`$6',`$5',`$4',`$3',`$2')'')
85 define(`swap8', ``8(`$1',`$9',`$8',`$7',`$6',`$5',`$4',`$3',`$2')'')
86 define(`sk0')
87 define(`prep', `define(`sk$1',
88   `pushdef(`t$2$3', $1(`$2$3',_rd(`$1', l$2$4)))')')
89 forloop(1, 8, `prep(', `, `$', 1, 2)')
90 define(`prep', `define(`sk$1', `sk8($2@)sk'eval($1-8)`(`$2$3',C)')')
91 forloop(9, 255, `prep(', `, `$', `1')')
93 define(`_rd', `_rd$1$2')
94 define(`_rd10', `ifelse(`$1', `', `define(`C', `$2')', `stack_reverse(`t$1',
95   `l$1')')_rd(1, l$1$2)')
96 define(`_rd11', ``$2'popdef(`l$1')')
97 define(`_rd12', ``$2'define(`l$1', `1(`$1',`$3')')')
98 define(`_rd13', ``$2'define(`l$1', `2(`$1',`$3',`$4')')')
99 define(`_rd14', ``$2'define(`l$1', `3(`$1',`$3',`$4',`$5')')')
100 define(`_rd15', ``$2'define(`l$1', `4(`$1',`$3',`$4',`$5',`$6')')')
101 define(`_rd16', ``$2'define(`l$1', `5(`$1',`$3',`$4',`$5',`$6',`$7')')')
102 define(`_rd17', ``$2'define(`l$1', `6(`$1',`$3',`$4',`$5',`$6',`$7',`$8')')')
103 define(`_rd18', ``$2'define(`l$1', `7(`$1',`$3',`$4',`$5',`$6',`$7',`$8',`$9')')')
104 define(`_rd20', `ifelse(`$1', `', `define(`C', `$2')', `stack_reverse(`t$1',
105   `l$1')')_rd(2, l$1$2)')
106 define(`_rd21', ``$2',popdef(`l$1')_rd(1, l$1)')
107 define(`_rd22', ``$2',`$3'popdef(`l$1')')
108 define(`_rd23', ``$2',`$3'define(`l$1', `1(`$1',`$4')')')
109 define(`_rd24', ``$2',`$3'define(`l$1', `2(`$1',`$4',`$5')')')
110 define(`_rd25', ``$2',`$3'define(`l$1', `3(`$1',`$4',`$5',`$6')')')
111 define(`_rd26', ``$2',`$3'define(`l$1', `4(`$1',`$4',`$5',`$6',`$7')')')
112 define(`_rd27', ``$2',`$3'define(`l$1', `5(`$1',`$4',`$5',`$6',`$7',`$8')')')
113 define(`_rd28', ``$2',`$3'define(`l$1', `6(`$1',`$4',`$5',`$6',`$7',`$8',`$9')')')
114 define(`_rd30', `ifelse(`$1', `', `define(`C', `$2')', `stack_reverse(`t$1',
115   `l$1')')_rd(3, l$1$2)')
116 define(`_rd31', ``$2',popdef(`l$1')_rd(2, l$1)')
117 define(`_rd32', ``$2',`$3',popdef(`l$1')_rd(1, l$1)')
118 define(`_rd33', ``$2',`$3',`$4'popdef(`l$1')')
119 define(`_rd34', ``$2',`$3',`$4'define(`l$1', `1(`$1',`$5')')')
120 define(`_rd35', ``$2',`$3',`$4'define(`l$1', `2(`$1',`$5',`$6')')')
121 define(`_rd36', ``$2',`$3',`$4'define(`l$1', `3(`$1',`$5',`$6',`$7')')')
122 define(`_rd37', ``$2',`$3',`$4'define(`l$1', `4(`$1',`$5',`$6',`$7',`$8')')')
123 define(`_rd38', ``$2',`$3',`$4'define(`l$1', `5(`$1',`$5',`$6',`$7',`$8',`$9')')')
124 define(`_rd40', `ifelse(`$1', `', `define(`C', `$2')', `stack_reverse(`t$1',
125   `l$1')')_rd(4, l$1$2)')
126 define(`_rd41', ``$2',popdef(`l$1')_rd(3, l$1)')
127 define(`_rd42', ``$2',`$3',popdef(`l$1')_rd(2, l$1)')
128 define(`_rd43', ``$2',`$3',`$4',popdef(`l$1')_rd(1, l$1)')
129 define(`_rd44', ``$2',`$3',`$4',`$5'popdef(`l$1')')
130 define(`_rd45', ``$2',`$3',`$4',`$5'define(`l$1', `1(`$1',`$6')')')
131 define(`_rd46', ``$2',`$3',`$4',`$5'define(`l$1', `2(`$1',`$6',`$7')')')
132 define(`_rd47', ``$2',`$3',`$4',`$5'define(`l$1', `3(`$1',`$6',`$7',`$8')')')
133 define(`_rd48', ``$2',`$3',`$4',`$5'define(`l$1', `4(`$1',`$6',`$7',`$8',`$9')')')
134 define(`_rd50', `ifelse(`$1', `', `define(`C', `$2')', `stack_reverse(`t$1',
135   `l$1')')_rd(5, l$1$2)')
136 define(`_rd51', ``$2',popdef(`l$1')_rd(4, l$1)')
137 define(`_rd52', ``$2',`$3',popdef(`l$1')_rd(3, l$1)')
138 define(`_rd53', ``$2',`$3',`$4',popdef(`l$1')_rd(2, l$1)')
139 define(`_rd54', ``$2',`$3',`$4',`$5',popdef(`l$1')_rd(1, l$1)')
140 define(`_rd55', ``$2',`$3',`$4',`$5',`$6'popdef(`l$1')')
141 define(`_rd56', ``$2',`$3',`$4',`$5',`$6'define(`l$1', `1(`$1',`$7')')')
142 define(`_rd57', ``$2',`$3',`$4',`$5',`$6'define(`l$1', `2(`$1',`$7',`$8')')')
143 define(`_rd58', ``$2',`$3',`$4',`$5',`$6'define(`l$1', `3(`$1',`$7',`$8',`$9')')')
144 define(`_rd60', `ifelse(`$1', `', `define(`C', `$2')', `stack_reverse(`t$1',
145   `l$1')')_rd(6, l$1$2)')
146 define(`_rd61', ``$2',popdef(`l$1')_rd(5, l$1)')
147 define(`_rd62', ``$2',`$3',popdef(`l$1')_rd(4, l$1)')
148 define(`_rd63', ``$2',`$3',`$4',popdef(`l$1')_rd(3, l$1)')
149 define(`_rd64', ``$2',`$3',`$4',`$5',popdef(`l$1')_rd(2, l$1)')
150 define(`_rd65', ``$2',`$3',`$4',`$5',`$6',popdef(`l$1')_rd(1, l$1)')
151 define(`_rd66', ``$2',`$3',`$4',`$5',`$6',`$7'popdef(`l$1')')
152 define(`_rd67', ``$2',`$3',`$4',`$5',`$6',`$7'define(`l$1', `1(`$1',`$8')')')
153 define(`_rd68', ``$2',`$3',`$4',`$5',`$6',`$7'define(`l$1', `2(`$1',`$8',`$9')')')
154 define(`_rd70', `ifelse(`$1', `', `define(`C', `$2')', `stack_reverse(`t$1',
155   `l$1')')_rd(7, l$1$2)')
156 define(`_rd71', ``$2',popdef(`l$1')_rd(6, l$1)')
157 define(`_rd72', ``$2',`$3',popdef(`l$1')_rd(5, l$1)')
158 define(`_rd73', ``$2',`$3',`$4',popdef(`l$1')_rd(4, l$1)')
159 define(`_rd74', ``$2',`$3',`$4',`$5',popdef(`l$1')_rd(3, l$1)')
160 define(`_rd75', ``$2',`$3',`$4',`$5',`$6',popdef(`l$1')_rd(2, l$1)')
161 define(`_rd76', ``$2',`$3',`$4',`$5',`$6',`$7',popdef(`l$1')_rd(1, l$1)')
162 define(`_rd77', ``$2',`$3',`$4',`$5',`$6',`$7',`$8'popdef(`l$1')')
163 define(`_rd78', ``$2',`$3',`$4',`$5',`$6',`$7',`$8'define(`l$1', `1(`$1',`$9')')')
164 define(`_rd80', `ifelse(`$1', `', `define(`C', `$2')', `stack_reverse(`t$1',
165   `l$1')')_rd(8, l$1$2)')
166 define(`_rd81', ``$2',popdef(`l$1')_rd(7, l$1)')
167 define(`_rd82', ``$2',`$3',popdef(`l$1')_rd(6, l$1)')
168 define(`_rd83', ``$2',`$3',`$4',popdef(`l$1')_rd(5, l$1)')
169 define(`_rd84', ``$2',`$3',`$4',`$5',popdef(`l$1')_rd(4, l$1)')
170 define(`_rd85', ``$2',`$3',`$4',`$5',`$6',popdef(`l$1')_rd(3, l$1)')
171 define(`_rd86', ``$2',`$3',`$4',`$5',`$6',`$7',popdef(`l$1')_rd(2, l$1)')
172 define(`_rd87', ``$2',`$3',`$4',`$5',`$6',`$7',`$8',popdef(`l$1')_rd(1, l$1)')
173 define(`_rd88', ``$2',`$3',`$4',`$5',`$6',`$7',`$8',`$9'popdef(`l$1')')
175 define(`p', 0)define(`s', 0)
176 define(`sk', `sk$1(`$2', `$3')pushdef(`t$2',
177   `0(,'incr(`$2')`)')define(`s', `$2')')
178 define(`rnd', `ifelse(`$1',,, `define(`p',eval((p+$1+s)&255))_$0($1, C,
179   incr(s))$0(shift($@))')')
180 define(`_rnd', `pushdef(`l$3', `0(`$3')')rv$1(`$3', `$2')sk(eval(s&255), `$3',
181   `$2')')
182 forloop(0, 63, `rnd(list)')
183 pushdef(`l'incr(s), 0(incr(s)))rv1(incr(s), C)sk(eval(255-p), incr(s), C)
184 define(`read', `_$0(_rd8$1)')
185 define(`_read', `$1^$2^$3^$4^$5^$6^$7^$8')
186 define(`dense', `eval(read(defn(`l'C))^read(defn(`l'C)), 16, 2)')
187 define(`part2', forloop_arg(0, 15, `dense'))
188 ', `errprintn(`unrecognized algo 'algo),m4exit(1)')
190 divert`'part1
191 part2