day 17 m4 optimize
[aoc_eblake.git] / 2020 / day9.m4
blobba32f61c770279fc52a5294ec50644d308455de7
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day9.input] [-Dpreamble=N] day9.m4
4 include(`common.m4')ifelse(common(9), `ok', `',
5 `errprint(`Missing common initialization
6 ')m4exit(1)')
7 ifdef(`preamble', `', `define(`preamble', 25)')
9 define(`list', translit(include(file), nl, `;'))
10 ifdef(`__gnu__', `
11   patsubst(defn(`list'), `\([^;]*\);', `pushdef(`val', `\1')')
12 ',`
13   define(`chew', `pushdef(`val', substr(`$1', 0, index(`$1', `;')))define(
14     `tail',substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'),
15     `;'), -1, `', `$0(defn(`tail'))')')
16   define(`Split', `ifelse(eval($1 < 35), 1, `chew(`$2')', `$0(eval($1/2),
17     substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2),
18     defn(`tail')substr(`$2', eval($1/2)))')')
19   Split(len(defn(`list')), defn(`list'))
22 define(`check', `ifelse($1, $2, `', `ifdef(`m'eval(($1 != 2 * $2) * ($1 - $2)),
23   1, `$0($1, defn(`m$2'))')')')
24 define(`do', `define(`m'last, $1)define(`last', $1)ifelse(check($1, head), `',
25   `define(`part1', $1)undefine(`t')', `define(`head',
26   defn(`m'head)popdef(`m'head))')')
27 pushdef(`do', `define(`m'last, $1)define(`last', $1)define(`iter',
28   incr(iter))ifelse(iter, preamble, `popdef(`do')')')
29 pushdef(`do', `define(`head', $1)define(`last', $1)define(`iter',
30   1)popdef(`do')')
31 stack_foreach(`val', `do')
33 define(`trimhead', `ifelse(eval(sum > 'part1`), 1, `define(`sum', eval(sum
34   - defn(`a'l)))define(`l', incr(l))$0()')')
35 define(`do', `trimhead()ifelse(sum, 'part1`, `undefine(`t')', `define(`r',
36   incr(r))define(`a'r, $1)define(`sum', eval(sum + $1))')')
37 pushdef(`do', `define(`l', 0)define(`r', 0)define(`a'r, $1)define(`sum',
38   $1)popdef(`do')')
39 stack_foreach(`val', `do')
40 define(`lo', part1)define(`hi', 0)
41 define(`find', `ifelse(eval($1 < lo), 1, `define(`lo', $1)', eval($1 > hi), 1,
42   `define(`hi', $1)')')
43 forloop(l, r, `find(a', `)')
44 define(`part2', eval(lo + hi))
46 divert`'part1
47 part2