1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day20.input] day20.m4
3 # Optionally use -Dverbose=1 to see some progress
5 include(`common.m4')ifelse(common(20), `ok', `',
6 `errprint(`Missing common initialization
9 define(`input', translit(include(defn(`file')), nl`.#', `;01'))
11 define(`parse', `patsubst(`$1', `.', `prep(`\&')')')
13 define(`chew', `ifelse($1, 1, `prep(`$2')', `$0(eval($1/2), substr(
14 `$2', 0, eval($1/2)))$0(eval($1-$1/2), substr(`$2', eval($1/2)))')')
15 define(`parse', `chew(len(`$1'), `$1')')
18 define(`prep', `define(`a'eval(count, 2, 9), $1)define(`count', incr(count))')
19 parse(substr(defn(`input'), 0, 512))
20 define(`a0', a000000000)define(`a1', a111111111)
21 ifelse(eval(a0 ^ a1), 1, `', `fatal(`unexpected rules')')
23 define(`x', offset)define(`y', offset)
24 define(`prep', `ifelse(`$1', `;', `define(`x', 'offset`)define(`y', incr(y))',
25 `define(`g0_'x`_'y, $1)define(`x', incr(x))')')
26 parse(substr(defn(`input'), 514))
27 define(`width', eval(y-x))
29 define(`do', `forloop($1, $2, `_$0(', `, $@)')')
30 define(`_do', `forloop($2, $3, `$4($1, ', `, `$5', $6)')')
31 define(`prep', `define(`g1_$1_$2', $3)')
32 do(0, eval(offset*2+width), `prep', a0)
33 define(`prep', `ifdef(`g0_$1_$2', `', `define(`g0_$1_$2', 0)')_$0(`$3',
34 decr($1), $1, incr($1), decr($2), $2, incr($2))')
35 define(`_prep', `define(`n$3_$6', `defn(`a'g$1_$2_$5()g$1_$3_$5()''dnl
36 ``g$1_$4_$5()g$1_$2_$6()g$1_$3_$6()g$1_$4_$6()g$1_$2_$7()''dnl
37 ``g$1_$3_$7()g$1_$4_$7())')')
38 do(1, eval(offset*2+width-1), `prep', `$'1)
40 define(`round', `output(1, `...$1')do(eval('offset`-$1),
41 eval('offset+width`+$1-1), `point', eval($1%2), eval(($1+1)%2))')
42 define(`D', defn(`define'))
43 define(`point', `D(`g$3_$1_$2', n$1_$2($4))')
44 define(`tally', `len(do(eval(offset-$1), eval(offset+width+$1-1), `_$0'))')
45 define(`_tally', `ifelse(g0_$1_$2, 1, `-')')
47 define(`part1', tally(2))
48 forloop_arg(3, 50, `round'))
49 define(`part2', tally(50))