day 25 optimize and improve heuristics
[aoc_eblake.git] / 2021 / day04.m4
blob85fe24454a8d2ce5db51cd3394a3e13746d6978c
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day04.input] day04.m4
4 include(`common.m4')ifelse(common(04), `ok', `',
5 `errprint(`Missing common initialization
6 ')m4exit(1)')
8 # First line is list, all remaining lines are 76 byte boards
9 define(`input', translit((include(defn(`file'))), `,()', ` '))
10 define(`offset', index(defn(`input'), nl))
11 define(`list', quote(translit(substr(defn(`input'), 0, offset), ` ', `,')))
12 define(`boards', translit(substr(defn(`input'), incr(offset)), nl, ` '))
13 define(`best', offset)define(`worst', `-1')
14 define(`setup', `_$0($*)')define(`_setup', `define(`m$2', `$1')')
15 define(`bingo', `eval(`($1 & ($1>>1) & ($1>>2) & ($1>>3) & ($1>>4) & 0x108421)
16   || ($1 & ($1>>5) & ($1>>10) & ($1>>15) & ($1>>20) & 0x1f)')')
17 define(`daub', `ifdef(`cur', `ifdef(`m$1', `+$1popdef(`m$1')')', `ifdef(`m$1',
18   `define(`set', eval(set | (1<<m$1)))popdef(`m$1')ifelse(bingo(set), 1,
19   `define(`cur', $1)')')define(`round', incr(round))')')
20 define(`score', `ifelse(eval($2 < best), 1, `define(`best', $2)define(`part1',
21   $1)')ifelse(eval($2 > worst), 1, `define(`worst', $2)define(`part2', $1)')')
22 define(`board', `
23   forloop_var(`i', 0, 24, `setup(i, substr(`$1', eval(i*3), 3))')
24   define(`set', 0)define(`round', 0)popdef(`cur')
25   score(eval((foreach(`daub', list))*cur), round)
27 ifdef(`__gnu__', `
28   dnl shame that GNU m4 regex lacks .{76}
29   patsubst(defn(`boards'), translit(format(`%076d', 0), 0, .), `board(`\&')')
30 ', `
31   define(`half', `eval($1/76/2*76)')
32   define(`chew', `ifelse($1, 76, `board(`$2')', `$0(half($1),
33     substr(`$2', 0, half($1)))$0(eval($1-half($1)), substr(`$2', half($1)))')')
34   chew(len(defn(`boards')), defn(`boards'))
37 divert`'part1
38 part2