day 2 golfed, sort of; 451 bytes
[aoc_eblake.git] / 2020 / day16.m4
blob1547f4df228b9992d933227cfda3ebba95ef26f0
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day16.input] day16.m4
4 include(`common.m4')ifelse(common(16), `ok', `',
5 `errprint(`Missing common initialization
6 ')m4exit(1)')
8 include(`math64.m4')
9 define(`or', `:')define(`part1', 0)define(`part2', 1)define(`slot', 0)
10 define(`input', translit((include(defn(`file'))), `-,'nl`() ', `::;'))
11 define(`valid', `_$0(slot, translit(`$1', `:', `,'))')
12 define(`_valid', `define(`s'eval(1<<$1), `$2')forloop($3, $4, `allow(',
13   `, $1)')forloop($5, $6, `allow(', `, $1)')define(`slot', incr($1))')
14 define(`allow', `define(`v$1', eval((defn(`v$1')+0) | (1<<$2)))')
15 define(`check', `narrow(foreach(`_$0', translit(`$1', `:', `,')))')
16 define(`_check', `, ifdef(`v$1', `v$1', `-define(`part1', eval(part1 + $1))')')
17 define(`narrow', `ifelse(index(`$*', -), -1, `_$0(0$@)')')
18 define(`_narrow', `define(`n$1', eval(n$1 & $2))ifelse(`$#', 2, `',
19   `$0(incr($1), shift(shift($@)))')')
20 ifdef(`__gnu__', `
21   define(`do', `patsubst(`$1', `\([^;]*\);', `$2(`\1')')')
22 ',`
23   define(`_chew', `$2(substr(`$1', 0, index(`$1', `;')))define(`tail',
24     substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'), `;'), -1,
25     `', `$0(defn(`tail'), `$2')')')
26   define(`chew', `ifelse(eval($1 < 160), 1, `_$0(`$2', `$3')', `$0(eval($1/2),
27     substr(`$2', 0, eval($1/2)), `$3')$0(eval(len(defn(`tail')) + $1 - $1/2),
28     defn(`tail')substr(`$2', eval($1/2)), `$3')')')
29   define(`do', `chew(len(`$1'), `$1', `$2')')
31 do(substr(defn(`input'), 0, incr(index(defn(`input'), `;;'))), `valid')
32 forloop(0, decr(slot), `define(`n'', `, 'eval((1 << slot) - 1)`)')
33 do(substr(defn(`input'), eval(index(defn(`input'), `kets:;') + 6)), `check')
34 forloop(0, decr(slot), `forloop_var(`i', 0, decr(slot), `ifdef(`s'defn(`n'i),
35   `define(`l'i, defn(`n'i))forloop_var(`j', 0, decr(slot), `define(`n'j,
36   eval(defn(`n'j) & ~defn(`l'i)))')')')')
37 define(`tally', `_$0(0, translit(`$1', `:', `,'))')
38 define(`_tally', `ifelse(index(defn(`s'l$1), `depart'), 0, `define(`part2',
39   mul64(part2, $2))')ifelse(`$#', 2, `', `$0(incr($1), shift(shift($@)))')')
40 tally(substr(defn(`input'), eval(index(defn(`input'), `ket:;') + 5),
41   eval(index(defn(`input'), `;;nea') - index(defn(`input'), `ket:;') - 5)))
43 divert`'part1
44 part2