1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day12.input] day12.m4
3 # Optionally use -Dlimit=N to control how long to run
4 # Optionally use -Dverbose=1 to see some progress
6 include(`common.m4')ifelse(common(12), `ok', `',
7 `errprint(`Missing common initialization
11 ifdef(`limit', `', `define(`limit', 1000)')
14 define(`parse', `_$0$1_$0$2_$0$3_$0$4')
15 define(`_parse', `$0_(cnt, $@)')
16 define(`_parse_', `define(`p$1x', $2)define(`p$1y', $3)define(`p$1z',
17 $4)define(`v$1x', 0)define(`v$1y', 0)define(`v$1z', 0)define(`cnt',
19 parse(translit((include(defn(`file'))), nl`<>(xyz=)', `,()'))
21 define(`copy', `ifdef(`$2', `', `define(`$2', defn(`$1'))')')
22 define(`check10000', `output(1, `...$1')copy(`$0',
23 `check'eval($1+10000))check($@)')
24 define(`c', ``(($1>$2)-($1<$2))'')
25 define(`g', `eval($5+c($2, $1)+c($3, $1)+c($4, $1))')
26 define(`round', `_$0(incr($1), $2, $3, $4, $5, g($2, $3, $4, $5, $6),
27 g($3, $2, $4, $5, $7), g($4, $2, $3, $5, $8), g($5, $2, $3, $4, $9))')
28 define(`v', `eval($1+$2)')
29 define(`_round', `ifdef(`check$1', `check$1', `check')($1, v($2, $6),
30 v($3, $7), v($4, $8), v($5, $9), $6, $7, $8, $9)')
31 define(`check', `ifelse($6$7$8$9, 0000, `first', `round')($1, $2, $3, $4,
33 define(`check'limit, `translit(`pushdef(`e0', `$2,$6')pushdef(`e1',
34 `$3,$7')pushdef(`e2', `$4,$8')pushdef(`e3', `$5,$9')', `-')check($@)')
35 define(`process', `_$0(`$1', round(0, p0$1, p1$1, p2$1, p3$1, v0$1, v1$1,
37 define(`_process', `ifelse(eval($2 < limit), 1, `define(`part1',
38 ``limit too small for part1'')')define(`per$1', eval(`2*$2'))')
39 process(`x')process(`y')process(`z')
40 define(`e', `_e(e$1, popdef(`e$1')e$1, popdef(`e$1')e$1)')
41 define(`_e', `($1+$3+$5)*($2+$4+$6)')
42 ifdef(`part1', `', `define(`part1', eval(e(0)+e(1)+e(2)+e(3)))')
44 define(`gcd', `ifelse($2, 0, $1, `$0($2, eval(`$1 % $2'))')')
45 define(`lcm', `mul64(eval($1 / gcd($1, $2)), $2)')
46 define(`part2', lcm(perx, pery))
47 define(`div', lcm(gcd(perx, perz), gcd(pery, perz)))
48 define(`part2', mul64(eval(perz / div), part2))