day 21 preliminary refactoring
[aoc_eblake.git] / 2020 / day14.m4
blob6ce8536da3e744ff799a0b226f03ab077d4df1c4
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day14.input] [-Dhashsize=H] day14.m4
4 include(`common.m4')ifelse(common(14, 65537), `ok', `',
5 `errprint(`Missing common initialization
6 ')m4exit(1)')
8 include(`math64.m4')
9 define(`input', include(defn(`file')))
10 define(`p1h', 0)define(`p1l', 0)define(`p2', 0)
11 define(`mask', `define(`m', `$1')')
12 define(`mem', `ifdef(`m1h_$1', `define(`p1h', eval(p1h - m1h_$1))define(`p1l',
13   eval(p1l - m1l_$1))')define(`tmp', `visit($1, eval($'1`, 2, 36), $'1`)')tmp')
14 define(`visit', `$0_1($1, m, $2)_foreach(`$0_2($3,', `)', addr(m,
15   eval($1, 2, 36)))')
16 define(`visit_1', `define(`m1h_$1', merge(0, substr($2, 0, 18), substr($3, 0,
17   18)))define(`m1l_$1', merge(0, substr($2, 18), substr($3, 18)))define(`p1h',
18   eval(p1h + m1h_$1))define(`p1l', eval(p1l + m1l_$1))')
19 ifdef(`__gnu__', `
20   define(`merge', `eval((0b$3 | 0b`'translit($2, `X', 0)) &
21     0b`'translit($2, `X', 1))')
22 ', `
23   define(`merge', `ifelse(`$2', `', `$1', `$0(eval(2 * $1 + _$0(substr(`$2', 0,
24     1), substr(`$3', 0,  1))), substr(`$2', 1), substr(`$3', 1))')')
25   define(`_merge', `ifelse(`$1', 1, 1, `$1', 0, 0, $2)')
27 define(`big', `errprintn(`input branches too much for part 2')pushdef(`big')')
28 define(`addr', `ifelse(eval(len(translit($1, 01)) > 9), 1, `big()', index(`$1',
29   `X'), -1, `_$0(translit($1, -0, `0X'), $2)', `addr(substr(`$1', 0, index(`$1',
30   `X'))`'-substr(`$1', incr(index(`$1', `X'))), $2)addr(substr(`$1', 0,
31   index(`$1', `X'))`'1substr(`$1', incr(index(`$1', `X'))), $2)')')
32 define(`_addr', `, eval(merge(0, substr($1, 0, 18), substr($2, 0, 18)), 2,
33   18)eval(merge(0, substr($1, 18), substr($2, 18)), 2, 18)')
34 define(`visit_2', `ifdef(`m2_$2', `ifelse(index(p2, -), -1, `define(`p2',
35   eval(p2 - m2_$2))', `pushdef(`p2', -m2_$2)')')define(`m2_$2',
36   $1)ifelse(eval(p2 + $1 > $1), 1, `define(`p2', eval(p2 + $1))',
37   `pushdef(`p2', $1)')')
39 translit(defn(`input'), =nl`[] ', `()()')
40 define(`part1', add64(mul64(p1h, eval(1<<18)), p1l))
41 define(`do', `ifdef(`p2', `define(`part2', add64(part2, p2))popdef(`p2')do()')')
42 define(`part2', 0)do()
44 divert`'part1
45 part2