1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dseed=XYZ] [-Dfile=day14.input] day14.m4
3 # Optionally use -Dverbose=1 to see some progress
5 include(`common.m4')ifelse(common(14, 65537), `ok', `',
6 `errprint(`Missing common initialization
9 ifdef(`seed', `', `define(`seed', translit(include(defn(`file')), nl))')
11 define(`D', defn(`define'))define(`E', defn(`eval'))
12 define(`prep', `define(`I$1', dquote(incr($1)))')
13 forloop_arg(0, 254, `prep')
15 define(`prep', `define(`D$1', dquote(decr($1)))')
16 forloop_arg(1, 255, `prep')
18 define(`_reset', `D(`A$1', $1)')
19 define(`reset', `undefine(`list')forloop_arg(0, 255, `_$0')D(`P', 0)D(`S', 0)')
20 define(`W', `D(`A$1',A$2`'D(`A$2',A$1))')
21 define(`R', `R$1(`$2',E(`$2+$1-1&255'))D(`P',E(`$2+$3+$1&255'))D(`S',I$3)')
22 define(`prep', `define(`R$1', `W($'`@)R'decr(D$1)`(I$'1`,D$'2`)')')
23 forloop_arg(2, 255, `prep')
24 define(`R0')define(`R1')
25 define(`set', `define(`V$1', eval($1 + $2))')
26 forloop(0, 9, `set(', `, 48)')
28 define(`set', `define(`V'eval($1+9, 36), eval($1 + $2))')
29 forloop(1, 26, `set(', `, 96)')
30 define(`split', `ifelse(`$1',, `_foreach(`pushdef(`list',', `)',, 17, 31, 73,
31 47, 23)', `pushdef(`list', defn(`V'substr(`$1', 0, 1)))$0(substr(`$1', 1))')')
32 define(`dense', `grid(E(0forloop(E(`$1*16'), E(`$1*16+15'),
33 `^defn(`A'', `)')), E(`$1*8'), $2)')
34 define(`grid', `forloop(0, 7, `_$0($1, ', `, $2, 'incr($3)`)')')
35 define(`_grid', `ifelse(eval(`$1 & 1 << 7-$2'), 0, `',
36 `define(`g'eval(`$2+$3+1')`_$4')define(`part1', incr(part1))')')
37 define(`hash', `output(1, `...$1')reset()split(defn(`seed')`_$1')forloop(0, 63,
38 `_stack_foreach(`list', `R(', `, P, S)', `T')')forloop(0, 15,
40 forloop_arg(0, 127, `hash')
42 define(`mark', `ifdef(`g$1_$2', `ifelse(g$1_$2, `', `_$0($1, $2,
43 part2)define(`part2', incr(part2))')')')
44 define(`_mark', `ifdef(`g$1_$2', `ifelse(g$1_$2, `', `define(`g$1_$2',
45 $3)$0(incr($1), $2, $3)$0($1, incr($2), $3)$0(decr($1), $2, $3)$0($1,
47 define(`row', `forloop(1, 128, `mark(', `, $1)')')
48 forloop_arg(1, 128, `row')