day 17 m4 optimize
[aoc_eblake.git] / 2020 / day7.m4
blob4799b1a15d874566ddb31b85186fa2f26f709d1e
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day7.input] day7.m4
4 include(`common.m4')ifelse(common(7), `ok', `',
5 `errprint(`Missing common initialization
6 ')m4exit(1)')
8 define(`contain')define(`no')define(`other')define(`bag')define(`bags')
9 define(`list', quote(translit((include(file)), `,()'nl)))
10 ifdef(`__gnu__', `
11   define(`list', patsubst((defn(`list')), `\([a-z]+\) \([a-z]+\)',
12     `\1_\2,'))
13   define(`list', patsubst(defn(`list'), `\([0-9]\) \(\w+\),', `(\1, \2),'))
14   patsubst(defn(`list'), `\(\w+\), *\([^.]*\)\.', `pushdef(`names',
15     `\1')define(`n_\1', `\2')')
16 ',`
17   define(`node', `pushdef(`names', `$1_$2')define(`n_$1_$2',
18     quote(collect(shift(shift($@)))))')
19   define(`collect', `ifelse(`$#', 1, `', len(`$1'), 1,
20     `($1, `$2_$3'),$0(shift(shift(shift($@))))', `$0(shift($@))')')
21   define(`chew', `node(translit(substr(`$1', 0, index(`$1', `.')), ` ',
22     `,'))define(`tail',substr(`$1', incr(index(`$1', `.'))))ifelse(index(defn(
23     `tail'), `.'), -1, `', `$0(defn(`tail'))')')
24   define(`split', `ifelse(eval($1 < 170), 1, `chew(`$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   split(len(defn(`list')), defn(`list'))
30 define(`g_shiny_gold', +0)
31 define(`check', `ifelse(`$1', `', `', `_$0$1')')define(`_check', `good(`$2')')
32 define(`good', `ifdef(`g_$1', `', `define(`g_$1', ifelse(foreach(`check',
33   n_$1), `', `', +1))')g_$1')
34 define(`part1', eval(stack_foreach(`names', `good')))
35 define(`holds', `ifelse(`$1', `', `', `_$0$1')')
36 define(`_holds', `+ $1 * count(`$2')')
37 define(`count', `ifdef(`c_$1', `', `define(`c_$1', eval(1 foreach(`holds',
38   n_$1)))')c_$1')
39 define(`part2', decr(count(`shiny_gold')))
41 divert`'part1
42 part2