1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day15.input] [-Drow=N] [-Dbound=N] day15.m4
3 # Defaults: row=10 bound=20 for file=*tmp.*, 2000000/4000000 otherwise
5 include(`common.m4')ifelse(common(15), `ok', `',
6 `errprint(`Missing common initialization
8 ifdef(`row', `', `define(`row', ifelse(index(defn(`file'), `tmp.'), -1,
10 ifdef(`bound', `', `define(`bound', ifelse(index(defn(`file'), `tmp.'), -1,
13 define(`ranges')define(`offset', 0)define(`diags')define(`diffs')
14 define(`delta', `(($1 - $2)*($1>$2) + ($2 - $1)*($2>$1))')
15 define(`dist', `eval(delta($1, $3)+delta($2, $4))')
16 define(`cmp', `ifelse(eval(`$1$2$3'), 1, `$1', `$3')')
17 define(`merge', `ifelse(`$3', `', ``,$@'', `ifelse(eval(`$2<$3'), 1, ``,$@'',
18 `ifelse(eval(`$4<$1'), 1, ``,`$3',`$4''merge(`$1', `$2'', `merge(cmp(`$1',
19 `<', `$3'), cmp(`$2', `>', `$4')'), shift(shift(shift(shift($@)))))')')')
21 define(`edge', `ifelse(eval(`$2>=0&&$2<2*''bound`), 1, `ifdef(`$3$2',
22 `ifelse(eval($3$2+$4), 3, `define(`$3$2', 3)define(`$3s',
23 `,'eval($1)defn(`$3s'))')', `define(`$3$2', $4)')')')
24 define(`diag', `edge($1, eval($1), `$0', $2)')
25 define(`diff', `edge($1, eval($1+'bound`), `$0', $2)')
26 define(`scan', `ifelse(eval(`$5>=$6'), 1, `define(`ranges', merge(eval(
27 `$1-$5+$6'), eval(`$1+$5-$6+1')ranges))ifelse(`$4', ''row``, `ifdef(`b$3_$4',
28 `', `define(`b$3_$4')define(`offset', incr(offset))')')')diag(`$1+$2-$5-1',
29 1)diag(`$1+$2+$5+1', 2)diff(`$1-$2-$5-1', 1)diff(`+$1-$2+$5+1', 2)')
30 define(`S', `scan($@, dist($@), delta($2, 'row`))')
31 translit((include(defn(`file'))), `r:'nl`= a-z()', `(,)')
33 define(`collect', `ifelse(`$2', `', `$1', `$0(eval(`$1 + $3 - $2'),
34 shift(shift(shift($@))))')')
35 define(`part1', eval(collect(-offset`'ranges)))
36 define(`_score', `eval(`$1*4+$2/1000000')eval(`$2%1000000', `', 6)')
37 define(`score', `ifelse(`$#', 4, `_$0(`($2 + $4)/2', `($2 - $4)/2')',
38 ``more work needed: $*'')')
39 define(`part2', score(diags, diffs))