day 25 optimize and improve heuristics
[aoc_eblake.git] / 2023 / day22.m4
blobf87fd54f75a3836073d61f8229eb2f388164bb84
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Ddata=day22.input] day22.m4
4 include(`common.m4')ifelse(common(22), `ok', `',
5 `errprint(`Missing common initialization
6 ')m4exit(1)')
8 dnl Transition away from fifth glyph
9 define(`macro', defn(`define'))
10 macro(`guts', defn(`defn'))
11 macro(`window', guts(`divert'))
12 macro(`push', guts(`pushdef'))
13 macro(`pop', guts(`popdef'))
14 macro(`load', `include($@)')dnl thanks to common.m4
15 macro(`math', guts(`eval'))
16 macro(`count', guts(`len'))
17 macro(`spot', guts(`index'))
18 ifdef(`data', `', `macro(`data', guts(`file'))')
20 macro(`input', translit((load(guts(`data'))), nl`~,()', `;..'))
21 macro(`grow', `macro(`$1', guts(`$1')`$2')')
22 macro(`bricks', 0)macro(`dim1', 0)macro(`dim2', 0)macro(`dim3', 0)
23 macro(`saturation', `ifelse(math($2>$1), 1, `macro(`$1', $2)')')
24 macro(`_do', `macro(`brick$1', `$2,$3,$4,$5,$6,$7')macro(`supports$1')macro(
25   `atop$1')saturation(`dim1', $5)saturation(`dim2', $6)saturation(`dim3',
26   $4)push(`rank$4', $1)')
27 macro(`do', `_$0($1, translit(`$2', `.', `,'))macro(`bricks', $1)')
29 ifdef(`__gnu__', `
30   patsubst(guts(`input'), `\([^;]*\);', `do(incr(bricks), `\1')')
31 ', `
32   macro(`_chomp', `do(incr(bricks), substr(`$1', 0, spot(`$1', `;')))macro(
33     `tail', substr(`$1', incr(spot(`$1', `;'))))ifelse(spot(guts(`tail'),
34     `;'), -1, `', `$0(guts(`tail'))')')
35   macro(`chomp', `ifelse(math($1 < 32), 1, `_$0(`$2')', `$0(math($1/2),
36     substr(`$2', 0, math($1/2)))$0(math(count(guts(`tail')) + $1 - $1/2),
37     guts(`tail')substr(`$2', math($1/2)))')')
38   chomp(count(guts(`input')), guts(`input'))
41 macro(`_init', `macro(`tall$1_$2', 0)')
42 macro(`init', `forloop(0, dim2, `_$0($1, ', `)')')
43 forloop_arg(0, dim1, `init')
44 macro(`_findtop', `forloop($2, $3, `saturation(`top', guts(`tall$1_'', `))')')
45 macro(`findtop', `macro(`top', 0)forloop($1, $2, `_$0(', `, $3, $4)')top')
46 macro(`_land', `ifdef(`at$2_$3_$4', `grow(`atop$1', at$2_$3_$4`,')grow(
47   `supports'at$2_$3_$4, `$1,')')macro(`tall$2_$3', $5)macro(`at$2_$3_$5', $1)')
48 macro(`land', `forloop($3, $4, `_$0($1, $2, ', `, $5, $6)')')
49 macro(`_position', `forloop($2, $5, `land($1, ', `, $3, $6, $8,
50   'math($8+$7-$4+1)`)')')
51 macro(`position', `_$0($@, findtop($2, $5, $3, $6))')
52 macro(`fall', `ifdef(`rank$1', `position(rank$1, first(`brick'rank$1))pop(
53   `rank$1')$0($@)')')
54 forloop_arg(1, dim3, `fall')
56 macro(`assay', `ifelse($1, `', `', $1, $2, `$0(shift($@))', $2, `',
57   `macro(`risky$1')')')
58 forloop(1, bricks, `assay(first(`atop'', `))')
59 macro(`part1', count(forloop(1, bricks, `ifdef(`risky'', `, `', `-')')))
61 macro(`part2', 0)
62 macro(`mop', `ifdef(`list', `pop(guts(`list'))pop(`list')$0()')')
63 macro(`_audit', `ifelse($2, `', `macro(`part2', incr(part2))pull($1)',
64   `ifdef(`bad$2', `$0($1, shift(shift($@)))')')')
65 macro(`audit', `ifelse($2, `', `', $2, $3, `$0($1, shift(shift($@)))',
66   `_$0($2, atop$2)$0($1, shift(shift($@)))')')
67 macro(`pull', `ifdef(`bad$1', `', `push(`bad$1')push(`list',
68   `bad$1')audit(`$1', supports$1)')')
69 forloop(1, bricks, `pull(', `)mop()')
71 window`'part1
72 part2