day 20 part 1
[aoc_eblake.git] / 2023 / day20.m4
blobe83c0f7f0074b24c470c80d224bda4acc1bfb2af
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day20.input] day20.m4
4 include(`common.m4')ifelse(common(20), `ok', `',
5 `errprint(`Missing common initialization
6 ')m4exit(1)')
8 # Other than example and broadcaster, names are two lower letters; avoid
9 # collisions with the nl macro.
10 define(`Nl', defn(`nl'))undefine(`nl')
11 define(`errprintn', `errprint(`$1'Nl())')
12 define(`output', `ifelse(`$#', 0, ``$0'', 'dquote(defn(`output'))`)')
14 define(`input', translit((include(defn(`file'))), Nl`,> ()-', `;..'))
15 define(`bump', `define(`$1', incr($1))')
16 define(`q_h', 0)define(`q_t', 0)
17 define(`sent0', 0)define(`sent1', 0)
18 define(`_send', `bump(`sent$2')define(`q_'q_t,
19   `define(`$1_$3', $2)$3_($2)')bump(`q_t')')
20 define(`send', `_foreach(`_$0(`$1', $2, ', `)', o_$1)')
21 define(`broad', `bump(`sent0')send(`brd', 0)')
22 define(`_flip', `define(`s_$1', $2)send(`$1', $2)')
23 define(`flip', `ifelse($1, 0, `_$0(`$2', eval(!s_$2))')')
24 define(`conj', `send(`$2', eval(!(1_foreach(`first(`*'', `_$2)', i_$2))))')
26 define(`_wire', `define(`o_$1', defn(`o_$1')`,`$2'')define(`i_$2',
27   defn(`i_$2')`,`$1'')define(`$1_$2', 0)ifdef(`$2_', `', `define(`$2_')')')
28 define(`wire', `_foreach(`_$0(`$1', ', `)', $@)')
29 define(`_do', `ifelse(`$1', `b', `wire(`brd', shift(shift($@)))', `$1',
30   `%', `define(`$2_', `flip('$`1, `$2')')wire(shift($@))define(`s_$2', 0)',
31   `$1', `&', `define(`$2_', `conj('$`1, `$2')')wire(shift($@))')')
32 define(`do', `_$0(substr(`$1', 0, 1), translit(`$1', `.%&', `,'))')
34 ifdef(`__gnu__', `
35   patsubst(defn(`input'), `\([^;]*\);', `do(`\1')')
36 ', `
37   define(`_chew', `do(substr(`$1', 0, index(`$1', `;')))define(
38     `tail', substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'),
39     `;'), -1, `', `$0(defn(`tail'))')')
40   define(`chew', `ifelse(eval($1 < 20), 1, `_$0(`$2')', `$0(eval($1/2),
41     substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2),
42     defn(`tail')substr(`$2', eval($1/2)))')')
43   chew(len(defn(`input')), defn(`input'))
46 define(`_round', `ifelse(q_h, q_t, `', `first(`q_'q_h`()')popdef(`q_'q_h)bump(
47   `q_h')$0()')')
48 define(`round', `broad()_$0()')
49 forloop_arg(1, 1000, `round')
50 define(`part1', eval(sent0*sent1))
52 divert`'part1
53 part2