day 25 optimize and improve heuristics
[aoc_eblake.git] / 2023 / day07.m4
blobba6fb1347c1ef0302b9e28db9b2d71875c132144
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day07.input] day07.m4
3 # Optionally use -Dverbose=1 to see some progress
5 include(`common.m4')ifelse(common(07), `ok', `',
6 `errprint(`Missing common initialization
7 ')m4exit(1)')
9 # Careful not to collide with hex digits.  eval(12,16) outputs unquoted c.
10 define(`card', 0)
11 define(`input', translit(include(defn(`file')), nl` ', `;.'))
13 # https://www.reddit.com/r/adventofcode/comments/18cnzbm/comment/kcc4azi/
14 # Summing the histograms of each letter, and accounting for J in part 2,
15 # is sufficient to come up with a 2-digit number (25, 17, 13, 11, 9, 7, 5)
16 # that correctly ranks all possible hands.  One step further and we get
17 # a 1-digit hex number (a, 6, 4, 3, 2, 1, 0), for smaller integers.
18 define(`histo', `len(translit(`$1', `$2$1', `$2'))')
19 define(`best', `ifelse($1, 5, 5, $1, 4, 4, $2, 4, 4, $1, 3, 3, $2, 3, 3,
20   $3, 3, 3, $1, 2, 2, $2, 2, 2, $3, 2, 2, $4, 2, 2, $1)')
21 define(`_hand', `eval(`($1+$2+$3+$4+$5 + $6*$6+$6*2*'best($@)`) / 2 - 2', 16)')
22 define(`hand', `_$0(translit(`histo(`ABCDE', `A'), histo(`ABCDE', `B'),
23   histo(`ABCDE', `C'), histo(`ABCDE', `D'), histo(`ABCDE', `E')', `ABCDE',
24   `$1'), ($2+0))')
25 define(`Hand', `hand(translit(`$1', `J'), histo(`$1', `J'))')
26 define(`_do', `define(`s$1', eval(`0x'hand(`$2')`'translit(`$2', `AKQJT',
27   `edcba')))define(`S$1', eval(`0x'Hand(`$2')`'translit(`$2', `AKQJT',
28   `edc1a')))')
29 define(`do', `translit(`_$0($1, `ABCDE')define(`bid$1', `GHIJ')', `ABCDEFGHIJ',
30   `$2')define(`card', `$1')')
32 ifdef(`__gnu__', `
33   define(`eat', `patsubst(`$1', `\([^;]*\);', `do(incr(card), `\1')')')
34 ', `
35   define(`_chew', `do(incr(card), substr(`$1', 0, index(`$1', `;')))define(
36     `tail', substr(`$1', incr(index(`$1', `;'))))ifelse(index(defn(`tail'),
37     `;'), -1, `', `$0(defn(`tail'))')')
38   define(`chew', `ifelse(eval($1 < 20), 1, `_$0(`$2')', `$0(eval($1/2),
39     substr(`$2', 0, eval($1/2)))$0(eval(len(defn(`tail')) + $1 - $1/2),
40     defn(`tail')substr(`$2', eval($1/2)))')')
41   define(`eat', `chew(len(`$1'), `$1')')
43 eat(defn(`input'))
45 # Writing sort in m4 is a chore,
46 # And I know that from my days of yore,
47 # But I remembered last year
48 # Writing A* with cheer
49 # So crib my min-heap for the score!
50 define(`priority', 5)
51 include(`priority.m4')
53 define(`build', `insert(s$1, $1)')
54 forloop_arg(1, card, `build')
55 define(`value', `+$1*defn(`bid'shift(pop))')
56 define(`part1', eval(forloop_arg(1, card, `value')))
58 define(`build', `insert(S$1, $1)')
59 forloop_arg(1, card, `build')
60 define(`part2', eval(forloop_arg(1, card, `value')))
62 divert`'part1
63 part2