1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day21.input] day21.m4
4 include(`common.m4')ifelse(common(21), `ok', `',
5 `errprint(`Missing common initialization
9 # div64 is not in math64.m4 because it is not fully generic; but it is good
10 # enough for the few large divisions seen in this puzzle
11 define(`bits', `_$0(eval($1, 2))')
12 define(`_bits', ifdef(`__gnu__', ``shift(patsubst($1, ., `, \&'))'',
13 ``ifelse(len($1), 1, `$1', `substr($1, 0, 1),$0(substr($1, 1))')''))
14 define(`bits64', `ifelse(eval(len($1) < 10), 1, `bits($1)', `_$0(mul64($1,
15 5)), eval(substr($1, decr(len($1))) & 1)')')
16 define(`_bits64', `bits64(substr($1, 0, decr(len($1))))')
17 define(`div64p', `ifelse($4, `', `$1,$2', `$0(_$0(add64($1, $1), add64(add64($2,
18 $2), $4), $3), $3, shift(shift(shift(shift($@)))))')')
19 define(`_div64p', `ifelse(lt64($2, $3), 0, `add64($1, 1), sub64($2, $3)',
21 define(`div64', `ifelse(eval(`$1'), `$1', `eval(`$1/$2')',
22 `first($0p(0, 0, $2, bits64(`$1')))')')
24 define(`input', translit(include(defn(`file')), nl`:', `;'))
25 define(`_do', `define(`$1_', `e(`$2', `$3', `$4')')')
26 define(`do', `_$0(translit(`$1', ` ', `,'))')
29 patsubst(defn(`input'), `\([^;]*\);', `do(`\1')')
31 define(`_chew', `do(substr(`$1', 0, index(`$1', `;')))define(
32 `tail', substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'),
33 `;'), -1, `', `$0(defn(`tail'))')')
34 define(`chew', `ifelse(eval($1 < 35), 1, `_$0(`$2')', `$0(eval($1/2),
35 substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2),
36 defn(`tail')substr(`$2', eval($1/2)))')')
37 chew(len(defn(`input')), defn(`input'))
39 define(`_e', `ifelse(`$1', `@', `pushdef(`undo', `popdef(`undo')undo(_e(
40 $'1`,'translit(`$2', `-*/+', `+/*-')`,`$3'))')@', `$3', `@', `pushdef(`undo',
41 `popdef(`undo')undo(_e('ifelse(`$2', `+', ``$'1`,-,$1'', `$2', `-',
42 ``$1,-,$'1', `$2', `*', ``$'1`,/,$1'', ``$1,/,$'1')`))')@', `ifelse(`$2',
43 `+', `add', `$2', `-', `sub', `$2', `*', `mul', `div')64(`$1', `$3')')')
44 define(`e', `ifelse(`$2', `', `$1', `_$0($1_, $2, $3_)')')
45 define(`part1', root_)
49 pushdef(`_e', `popdef(`$0')$1$3')