day 18 golfed m4 squeeze a bit more
[aoc_eblake.git] / 2019 / day24.m4
blob160d8be4ba2bf50427a8bd97635428f08f1bef7b
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day24.input] day24.m4
3 # Optionally use -Dlimit=NN for fewer generations in part 2
4 # Optionally use -Donly=[12] to skip a part
6 include(`common.m4')ifelse(common(24), `ok', `',
7 `errprint(`Missing common initialization
8 ')m4exit(1)')
10 define(`input', translit(include(defn(`file'))
11 , `.#
12 ', 01))
13 ifdef(`limit', `ifelse(eval(limit & 1), 1, `errprint(`Limit must be even
14 ')m4exit(1)')', `define(`limit', 200)')
16 define(`mapping', `_$0($1, substr(alpha, $1, 1))')
17 define(`_mapping', `define(`map$1', `$2')define(`map$2', $1)ifelse(substr(
18   input, $1, 1), 1, `define(`init', defn(`init')`$2')')')
19 forloop_arg(0, 24, `mapping')
21 define(`bit', `ifelse(index(`$2', defn(`map$1')), -1, 0, 1)')
22 define(`near', `ifelse(eval($1 > 4), 1, `define(`n$1', defn(`n$1')defn(
23   `map'eval($1 - 5)))')ifelse(eval($1 % 5), 4, `', `define(`n$1',
24   defn(`n$1')defn(`map'incr($1)))')ifelse(eval($1 < 20), 1, `define(`n$1',
25   defn(`n$1')defn(`map'eval($1 + 5)))')ifelse(eval($1 % 5), 0, `',
26   `define(`n$1', defn(`n$1')defn(`map'decr($1)))')')
27 forloop_arg(0, 24, `near')
28 define(`value', `eval(0forloop(0, 24, `_$0(', `, `$1')'))')
29 define(`_value', ` | (bit($1, `$2') << $1)')
30 define(`show', `forloop_var(`y_', 0, 4, `forloop_var(`x_', 0, 4,
31   `eval(bit(eval(x_ + 5 * y_), `$1'))')
32 ')')
34 define(`next', `ifelse($1, 01, `defn(`map$2')', $1, 011, `defn(`map$2')',
35   $1, 11, `defn(`map$2')')')
36 define(`build', `next(bit($1, `$2')translit(translit(```$2$3''', defn(`n$1'),
37   11111111), 'dquote(defn(`alpha')defn(`ALPHA')`_')`), $1)')
38 define(`hit')
39 define(`gen', `ifdef(`gen_$1$2$3', `hit()', `_$0(`$1',
40   `$2$3')')defn(`gen_$1$2$3')')
41 define(`_gen_', ``build($1, $$2)'')
42 forloop(0, 24, `define(`_gen', defn(`_gen')_gen_(', `, @))')
43 define(`_gen', `define(`gen_$1$2', 'defn(`_gen')`)')
44 define(`loop', `ifdef(`gen_$1_', `define(`part1', value(`$1'))',
45   `loop(gen(`$1', `_'))')')
47 ifelse(ifdef(`only', only, 1), 1, `
48 loop(defn(`init', `_'))
51 ifelse(ifdef(`only', only, 2), 2, `
52 define(`n12')
53 define(`n17', `swqUVWXY')
54 define(`n11', `gqkAFKPU')
55 define(`n7', `cigABCDE')
56 define(`n13', `iosEJOTY')
57 define(`edge', `define(`n'$1, defn(`n$1')`H')define(`n'eval($1 * 5 + 4),
58   defn(`n'eval($1 * 5 + 4))`N')define(`n'eval($1 + 20), defn(`n'eval($1 +
59   20))`R')define(`n'eval($1 * 5), defn(`n'eval($1 * 5))`L')')
60 forloop_arg(0, 4, `edge')
62 define(`g', `defn(`g$1_'eval($2 + 'limit` + 1))')
63 define(`setg', `define(`g$1_'eval($2 + 'limit` + 1), `$3')')
64 setg(0, 0, defn(`init'))
65 define(`multigen', `forloop(-$1, $1, `_$0(0, 1, ', `)')forloop(-$1, $1,
66   `_$0(1, 0, ', `)')')
67 define(`_multigen', `setg($2, $3, gen(g($1, $3), translit(dquote(g($1,
68   decr($3))), `hnrlabcdefgijkmopqstuvwxy', `HNRL'), translit(dquote(g($1,
69   incr($3))), `abcdejotyxwvupkfghilmnqrs', `ABCDEJOTYXWVUPKF')))')
70 forloop_arg(1, eval(limit / 2), `multigen')
72 define(`count', `define(`part2', eval(part2 + _$0(-$1) + _$0($1)))')
73 define(`_count', `len(g(0, $1))')
74 define(`part2', _count(0))
75 forloop_arg(1, eval(limit / 2), `count')
77 ')divert`'part1
78 part2