1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day8.input] day8.m4
4 include(`common.m4')ifelse(common(8), `ok', `',
5 `errprint(`Missing common initialization
8 define(`list', translit(include(file), nl, `;'))
10 patsubst(defn(`list'), `\(\w*\) \([^;]*\);', `pushdef(`inst', `\1(\2)')')
12 define(`line', `pushdef(`inst', `$1($2)')')
13 define(`chew', `line(translit(substr(`$1', 0, index(`$1', `;')), ` ',
14 `,'))define(`tail',substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(
15 `tail'), `;'), -1, `', `$0(defn(`tail'))')')
16 define(`split', `ifelse(eval($1 < 20), 1, `chew(`$2')', `$0(eval($1/2),
17 substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2),
18 defn(`tail')substr(`$2', eval($1/2)))')')
19 split(len(defn(`list')), defn(`list'))
22 define(`prep', `define(`p'pc, `$1')define(`pc', incr(pc))')
23 stack_foreach(`inst', `prep')
26 define(`acc', `define(`accum', eval(accum + $1))next(1)')
27 define(`nop', `next(1)')
28 define(`jmp', `next($1)')
29 define(`next', `latch()run(eval(pc + $1))')
30 define(`run', `define(`pc', $1)ifelse(eval($1 < 'max`)check($1, $2), 11,
33 define(`latch', `define(`w'pc, 1)')
34 define(`check', `ifdef(`w$1', $2, 1)')
35 define(`accum', 0)run(0)
36 define(`part1', accum)
37 define(`latch', `define(`w'pc, 2)')
38 define(`swap', `ifelse(`$2', `a', `', defn(`w$1'), 1, `1pushdef(`p$1',
39 ifelse(`$2', `n', ``jmp'', ``nop'')substr(defn(`p$1'), 3))')')
40 define(`done', `define(`check', 1)define(`accum', 0)run(0)define(`part2',
41 accum)pushdef(`try')')
42 define(`try', `ifelse(swap($1, substr(defn(`p$1'), 0, 1)), 1,
43 `run($1, 1)ifelse(eval(pc >= max), 1, `done`'')popdef(`p$1')')')')
44 forloop_arg(0, max, `try')