1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day12.input] day12.m4
4 include(`common.m4')ifelse(common(12), `ok', `',
5 `errprint(`Missing common initialization
9 define(`input', translit(include(defn(`file')), nl`.# =>', `;01'))
10 define(`init', substr(defn(`input'), incr(index(defn(`input'), `:')),
11 eval(index(defn(`input'), `;;') - index(defn(`input'), `:') - 1)))
12 define(`list', substr(defn(`input'), incr(incr(index(defn(`input'), `;;')))))
13 define(`visit', `translit(`define(`rABCDE', `F')define(`REDCBA', `F')',
16 patsubst(defn(`init'), `.', `pushdef(`st0', `\&')')
17 patsubst(defn(`list'), `\([^;]*\);', `visit(`\1')')
19 define(`chew', `ifelse(`$1', `1', `pushdef(`st0', `$2')', `$0(eval(`$1/2'),
20 substr(`$2', 0, eval(`$1/2')))$0(eval(`$1-$1/2'), substr(`$2',
22 chew(len(defn(`init')), defn(`init'))
23 define(`half', `eval($1/6/2*6)')
24 define(`chew', `ifelse(`$1', `6', `visit(`$2')', `$0(half(`$1'), substr(
25 `$2', 0, half(`$1')))$0(eval($1-half(`$1')), substr(`$2', half(`$1')))')')
26 chew(eval(len(defn(`list'))/7*6), translit(defn(`list'), `;'))
29 define(`prune', `ifelse($1, 0, `popdef(`$1')$2$0($@)')')
30 define(`rev', `_$0(0, 0, 0, 0, st0`'popdef(`st0'))prune(`st1',
31 `define(`offset', incr(offset))')')
32 define(`_rev', `pushdef(`st1', R$1$2$3$4$5)ifdef(`st0', `$0($2, $3, $4, $5,
33 st0`'popdef(`st0'))', `$0_($2, $3, $4, $5, 0)')')
34 define(`_rev_', `pushdef(`st1', R$1$2$3$4$5)pushdef(`st1',
35 R$2$3$4$5$5)pushdef(`st1', R$3$4$5$5$5)pushdef(`st1', R$4$5$5$5$5)define(
36 `offset', decr(decr(offset)))')
37 define(`fwd', `define(`sum', _$0(define(`offset', decr(decr(offset)))offset,
38 0, 0, 0, 0, 0, st1`'popdef(`st1')))prune(`st0')')
39 define(`_fwd', `pushdef(`st0', r$3$4$5$6$7)ifdef(`st1', `$0(incr($1),
40 eval($2+st0*$1), $4, $5, $6, $7, st1`'popdef(`st1'))', `$0_(incr($1),
41 eval($2+st0*$1), $4, $5, $6, $7, 0)')')
42 define(`_fwd_', `eval($2 + pushdef(`st0', r$3$4$5$6$7)st0*$1 +
43 pushdef(`st0', r$4$5$6$7$7)st0*($1+1) +
44 pushdef(`st0', r$5$6$7$7$7)st0*($1+2) +
45 pushdef(`st0', r$6$7$7$7$7)st0*($1+3))')
46 forloop_arg(0, 9, `rev()fwd')
49 define(`do', `define(`prev', sum)rev()fwd()ifelse(eval(sum - prev), diff,
50 `define(`part2', add64(mul64(add64(`50000000000', `-$1'), eval(diff/2)),
51 sum))', `define(`diff', eval(sum - prev))$0(incr(incr(`$1')))')')