1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day24.input] day24.m4
3 # Optionally use -Dlo=N -Dhi=N to alter bounds
4 # Optionally use -Dverbose=1 to see some progress
6 include(`common.m4')ifelse(common(24), `ok', `',
7 `errprint(`Missing common initialization
12 define(`input', translit((include(defn(`file'))), nl`,@ ()', `;..'))
14 define(`_do', `define(`p'p, `$*')define(`P'p, `$5, 'neg64($4)`, 'sub64(
15 mul64($2, $4), mul64($1, $5)))define(`p', incr(p))')
16 define(`do', `_$0(translit(`$1', `.', `,'))')
19 patsubst(defn(`input'), `\([^;]*\);', `do(`\1')')
21 define(`_chew', `do(substr(`$1', 0, index(`$1', `;')))define(
22 `tail', substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'),
23 `;'), -1, `', `$0(defn(`tail'))')')
24 define(`chew', `ifelse(eval($1 < 140), 1, `_$0(`$2')', `$0(eval($1/2),
25 substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2),
26 defn(`tail')substr(`$2', eval($1/2)))')')
27 chew(len(defn(`input')), defn(`input'))
30 # Default bounds based on size of input
31 ifdef(`lo', `', `define(`lo', ifelse(len(p), 1, 7, 200000000000000))')
32 ifdef(`hi', `', `define(`hi', ifelse(len(p), 1, 27, 400000000000000))')
34 define(`part1', 0)define(`prog', 0)
35 define(`progress', `ifelse(eval(prog%500), 0, `output(1, ...prog)')define(
37 define(`ge64', `lt64($2, $1)')
38 define(`le64', `ifelse($1, $2, 1, `lt64($1, $2)')')
39 define(`extract', `$1, $4')
40 define(`future', `ifelse(eval($4 < 0), 1, `le64', `ge64')($1, mul64($2, $3))')
41 define(`_compare', `ifelse(lt64($3, 0), 1, `$0(neg64($1), neg64($2), neg64($3),
42 $4, $5, $6, $7)', `ifelse(le64(mul64('lo`, $3), $1)le64($1, mul64('hi`,
43 $3))future($1, $3, $4, $5).le64(mul64('lo`, $3), $2)le64($2, mul64('hi`,
44 $3))future($1, $3, $6, $7), 111.111, `define(`part1', incr(part1))')')')
45 define(`compare', `_$0(sub64(mul64($2, $6), mul64($5, $3)), sub64(mul64($4, $3),
46 mul64($1, $6)), sub64(mul64($1, $5), mul64($4, $2)), extract(p$7),
47 extract(p$8))progress()')
48 define(`_probe', `compare(P$1, P$2, $1, $2)')
49 define(`probe', `forloop(incr($1), 'decr(p)`, `_$0($1, ', `)')')
50 forloop_arg(0, decr(decr(p)), `probe')