1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day19.input] day19.m4
4 include(`common.m4')ifelse(common(19), `ok', `',
5 `errprint(`Missing common initialization
8 define(`part1', 0)define(`part2', 0)
9 define(`input', include(defn(`file')))
12 define(`getrule', `define(`r$1', quote(translit(`$2', ` ', `,')))')
13 define(`match', `define(`$1', incr($1))')
14 patsubst(defn(`input'), `^\([0-9]*\): \(.*\)', `getrule(\1, \2)')
15 define(`patt', `ifdef(`p$1', `', `define(`p$1', build(r$1))')defn(`p$1')')
16 define(`build', `ifelse(`$1', `"a"', ``a'', `$1', `"b"', ``b'',
18 define(`_build', `ifelse(`$1', `', `_', `$1', `|', ``\|'',
19 `patt($1)')$0(shift($@))')
21 patsubst(defn(`input'), ^patt(0)$, `match(`part1')')
22 # Hard-coded to 0: 8 11, 8: 42 8, 11: 42 31 | 42 11 31, with no other 8/11
23 define(`check', `ifelse(eval(len(patsubst(`$2', patt(42), -)) >
24 len(patsubst(substr(`$1', len(`$2')), patt(31), -))), 1, `match(`part2')')')
25 ifdef(`r42', `patsubst(defn(`input'), `^\('patt(42)`+\)'patt(31)`+$',
26 `check(`\&', `\1')')', `define(`part2', ``not possible'')')
28 dnl Recursive match solution
29 define(`_chew', `$2(substr(`$1', 0, index(`$1', nl)))define(`tail',
30 substr(`$1', incr(index(`$1', nl))))ifelse(index(defn(`tail'), nl), -1,
31 `', `$0(defn(`tail'), `$2')')')
32 define(`chew', `ifelse(eval($1 < 400), 1, `_$0(`$2', `$3')', `$0(eval($1/2),
33 substr(`$2', 0, eval($1/2)), `$3')$0(eval(len(defn(`tail')) + $1 - $1/2),
34 defn(`tail')substr(`$2', eval($1/2)), `$3')')')
35 define(`do', `chew(len(`$1'), `$1', `$2')')
37 define(`getrule', `define(`r$1', translit(((translit(`$2', `| ', `p,'))),
39 define(`ruleline', `getrule(substr(`$1', 0, index(`$1', `:')), substr(`$1',
40 incr(incr(index(`$1', `:')))))')
41 do(substr(defn(`input'), 0, incr(index(defn(`input'), nl()nl))), `ruleline')
42 define(`match', `ifelse(`$1', `x', `x', `_foreach(`_$0(`$1', first(',
43 `), shift(shift($@)))', `', r$2)')')
44 define(`_match', `ifelse(good, `-', `', `$1$2$#', 2, `define(`good', `-')',
45 `$2$#', `2', `x', `$2', `', `$0(`$1', shift(shift($@)))', substr($2, 0, 1),
46 ", `ifelse(substr($1, 0, 1), substr($2, 1, 1), `$0(substr($1, 1),
47 shift(shift($@)))', `x')', `match($@)')')
48 define(`matchline', `define(`good', `')ifelse(`$1', `', `',
49 `translit(match(`$1', 0), `x')')good()')
50 define(`part1', len(do(substr(defn(`input'), index(defn(`input'), nl()nl)),
52 pushdef(`r8', ``42',`42,8'')pushdef(`r11',``42,31',`42,11,31'')
53 define(`part2', len(do(substr(defn(`input'), index(defn(`input'), nl()nl)),