1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dhashsize=H] [-Dfile=day18.input] day18.m4
4 include(`common.m4')ifelse(common(18, 65537), `ok', `',
5 `errprint(`Missing common initialization
8 define(`input', translit(include(defn(`file')), nl, `;'))
10 define(`line', `_$0(translit(`$1', ` ', `,'))')
11 define(`_line', `define(`i'cnt, `$1_')define(`a'cnt, ``$2',`$3'')ifelse(`$3',
12 8505, `pushdef(`i'cnt, `hck_')')define(`cnt', incr(cnt))ifdef(`r$2', `',
13 `ifelse(index(alpha, `$2'), -1, `', `pushdef(`regs', `$2')define(`r$2',
16 patsubst(defn(`input'), `\([^;]*\);', `line(`\1')')
18 define(`_chew', `line(substr(`$1', 0, index(`$1', `;')))define(`tail',
19 substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'), `;'), -1,
20 `', `$0(defn(`tail'))')')
21 define(`chew', `ifelse(eval($1 < 25), 1, `_$0(`$2')', `$0(eval($1/2),
22 substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2),
23 defn(`tail')substr(`$2', eval($1/2)))')')
24 chew(len(defn(`input')), defn(`input'))
27 define(`r_', `ifdef(`r$1', `r$2')$1')
28 define(`snd_', `define(`part1', r_(`$1', `$3'))incr($5)')
29 define(`set_', `define(`r$3$1', r_(`$2', `$3'))incr($5)')
30 define(`add_', `define(`r$3$1', eval(r$3$1 + r_(`$2', `$3')))incr($5)')
31 define(`mul_', `define(`r$3$1', eval(r$3$1 * r_(`$2', `$3')))incr($5)')
32 define(`mod_', `define(`r$3$1', eval(r$3$1 % r_(`$2', `$3')))incr($5)')
33 # peephole for a=0x7fffffff, p=(p*8505*129749+12345)%a
34 define(`hck_', `ifelse(r$3a, 2147483647, `define(`r$3p', R3(eval(12345+R(R(
35 r$3p, 8505), 129749))))', `errprintn(`peephole failed')m4exit(1)')eval($5+5)')
36 define(`R', `R1(eval(`($1>>16)*($2&0xffff)+$1*!!($2&0x10000)'),
37 eval(`($1&0xffff)*($2&0xffff)'))')
38 define(`R1', `R2($@, eval(`(($1&0x7fff)<<16)+($2&0x7fffffff)'))')
39 define(`R2', `R3(eval(`(($1>>15)&0x1ffff)+($2<0)+($3<0)+($3&0x7fffffff)'))')
40 define(`R3', `eval(`($1&0x7fffffff)+($1<0)')')
41 define(`rcv_', `ifelse(r_(`$1', `$3'), 0, `incr($5)', `pushdef(`run',
42 `popdef(`run')')$5')')
43 define(`jgz_', `ifelse(eval(r_(`$1', `$3')>0), 1, `eval($5+r_(`$2', `$3'))',
45 define(`run', `ifdef(`i$1', `_$0(i$1()(a$1, $3, $4, $1), incr($2),
47 define(`_run', `run($@)')
50 define(`q0h', 0)define(`q0t', 0)
51 define(`q1h', 0)define(`q1t', 0)
52 define(`pc0', 0)define(`pc1', 0)
53 define(`snd_', `define(`q$4_'q$4t, r_(`$1', `$3'))define(`q$4t',
55 define(`rcv_', `ifelse(q$3h, q$3t, `pushdef(`run',
56 `popdef(`run')save($'`@)')$5', `define(`r$3$1', defn(`q$3_'q$3h))popdef(
57 `q$3_'q$3h)define(`q$3h', incr(q$3h))incr($5)')')
58 define(`prep', `define(`r0$1', 0)define(`r1$1', 0)')
59 stack_foreach(`regs', `prep')
60 define(`r1p', 1)define(`inst', 0)
61 define(`save', `define(`pc$3', `$1')define(`inst', $2)')
62 define(`resume', `run(pc$1, inst, $1, eval(1-$1))')
63 define(`resolve', `ifelse(q0h.q1h, q0t.q1t, `', `resume(1)resume(0)$0()')')