1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dhashsize=H] [-Dfile=day23.input] day23.m4
4 include(`common.m4')ifelse(common(23, 65537), `ok', `',
5 `errprint(`Missing common initialization
8 define(`input', translit(include(defn(`file')), nl, `;'))
10 define(`line', `_$0(translit(`$1', ` ', `,'))')
11 define(`_line', `define(`i'cnt, `$1_')define(`a'cnt, ``$2',`$3'')define(`cnt',
12 incr(cnt))ifdef(`r$2', `', `ifelse(index(alpha, `$2'), -1, `',
13 `pushdef(`regs', `$2')define(`r$2', 0)')')')
15 patsubst(defn(`input'), `\([^;]*\);', `line(`\1')')
17 define(`_chew', `line(substr(`$1', 0, index(`$1', `;')))define(`tail',
18 substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'), `;'), -1,
19 `', `$0(defn(`tail'))')')
20 define(`chew', `ifelse(eval($1 < 28), 1, `_$0(`$2')', `$0(eval($1/2),
21 substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2),
22 defn(`tail')substr(`$2', eval($1/2)))')')
23 chew(len(defn(`input')), defn(`input'))
27 define(`r_', `ifdef(`r$1', `r')$1')
28 define(`set_', `define(`r$1', r_(`$2'))incr($3)')
29 define(`sub_', `define(`r$1', eval(r$1 - r_(`$2')))incr($3)')
30 define(`mul_', `define(`r$1', eval(r$1 * r_(`$2')))define(`part1',
31 incr(part1))incr($3)')
32 define(`jnz_', `ifelse(r_(`$1'), 0, `incr(`$3')', `eval($3+r_(`$2'))')')
33 define(`run', `ifdef(`i$1', `_$0(i$1()(a$1, $1), incr($2))')')
34 define(`_run', `run($@)')
37 _stack_foreach(`regs', `define(`r'', `, 0)', `t')
39 # For each b visited, the puzzle tests each pair 2<=d<=b and 2<=e<=b and sets
40 # f=0 if if finds any d*e==b. If b is prime, f stays 1. Then h is incremented
41 # based on f. This is therefore a major peephole optimization to do O(sqrt(N))
42 # instead of O(N^2) work per value of b.
43 define(`mul_', `ifelse(`$2', `e', `define(`rf', isprime(rb))eval(`$3+12')',
44 `define(`r$1', eval(r$1 * r_(`$2')))incr($3)')')
45 define(`isprime', `ifelse(eval(`$1&1'), 0, 0, `_$0(`$1', `3')')')
46 define(`_isprime', `ifelse(eval(`$2*$2>$1'), 1, 1, eval(`$1%$2'), 0, 0,
47 `$0(`$1', incr(incr(`$2')))')')