day 23 optimize again
[aoc_eblake.git] / 2016 / day5.m4
blob2c06d1ecfd5c6f0736fa133deab7422ae4d44952
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dmax=N] [-Dstart=NNN] [-Dprefix=XXX] [-Dfile=day5.input] day5.m4
3 # Optionally use -Donly=[12] to skip a part
4 # Optionally use -Dverbose=1 to see some progress
6 include(`common.m4')ifelse(common(5), `ok', `',
7 `errprint(`Missing common initialization
8 ')m4exit(1)')
10 ifdef(`start', `', `define(`start', 0)')
11 ifdef(`max', `', `define(`max', 8)')
12 ifdef(`prefix', `', `define(`prefix', translit(include(defn(`file')), nl))')
14 # Assume that prefix is [a-z]*, answer is [0-9]*.  Also assume prefix +
15 # answer < 32 bytes, thus only 1 md5 pass needed, and only result A matters.
16 define(`N', defn(`define'))define(`E', defn(`eval'))
17 define(`L', ``($1<<$2|($1>>1&0x7fffffff)>>31-$2)'')
18 define(`F', `N(`$1',E(`$2+'L(E($1`+($4^$2&($3^$4))+$5+$7'),`$6')))')
19 define(`G', `N(`$1',E(`$2+'L(E($1`+($3^$4&($2^$3))+$5+$7'),`$6')))')
20 define(`H', `N(`$1',E(`$2+'L(E($1`+($2^$3^$4)+$5+$7'),`$6')))')
21 define(`I', `N(`$1',E(`$2+'L(E($1`+($3^($2|~$4))+$5+$7'),`$6')))')
22 define(`set', `define(`V$1', eval($1 + $2))')
23 forloop(0, 9, `set(', `, 48)')
24 define(`set', `define(`V'eval(9 + $1, 36), eval($1 + $2))')
25 forloop(1, 26, `set(', `, 96)')
26 define(`S0', `N(`X$2',$1)')
27 define(`S1', `N(`X$2',E(X$2|$1`<<8'))')
28 define(`S2', `N(`X$2',E(X$2|$1`<<16'))')
29 define(`S3', `N(`X$2',E(X$2|$1`<<24'))')
30 forloop(0, 15, `define(`X'eval(', `,16), 0)')
31 define(`_P', `ifelse(`$1',,`S$3(128,$2)',`S$3(`V'substr(`$1',0,1),$2,$3)$0(
32   substr(`$1',1),ifelse($3,3,`incr($2),0',`$2,incr($3)'))')')
33 ifelse(E(len(defn(`prefix'))), 8, `_P(defn(`prefix'), 0, 0)
34   define(`P', `N(`Xe',E(len($1)`*8+64'))_$0(`$1',2,0)')', `define(`P',
35   `N(`Xe',E(len(defn(`prefix')$1)`*8'))_$0(defn(`prefix')`$1',0,0)')')
36 define(`md5', `P(`$1')_$0(`1732584193',`-271733879',`-1732584194',`271733878')')
37 define(`_md5', `N(`A',`$1')N(`B',`$2')N(`C',`$3')N(`D',`$4')'dnl
38 `F(`A',B,C,D,X0,7,`0xd76aa478')'dnl
39 `F(`D',A,B,C,X1,12,`0xe8c7b756')'dnl
40 `F(`C',D,A,B,X2,17,`0x242070db')'dnl
41 `F(`B',C,D,A,X3,22,`0xc1bdceee')'dnl
42 `F(`A',B,C,D,X4,7,`0xf57c0faf')'dnl
43 `F(`D',A,B,C,X5,12,`0x4787c62a')'dnl
44 `F(`C',D,A,B,X6,17,`0xa8304613')'dnl
45 `F(`B',C,D,A,X7,22,`0xfd469501')'dnl
46 `F(`A',B,C,D,X8,7,`0x698098d8')'dnl
47 `F(`D',A,B,C,X9,12,`0x8b44f7af')'dnl
48 `F(`C',D,A,B,Xa,17,`0xffff5bb1')'dnl
49 `F(`B',C,D,A,Xb,22,`0x895cd7be')'dnl
50 `F(`A',B,C,D,Xc,7,`0x6b901122')'dnl
51 `F(`D',A,B,C,Xd,12,`0xfd987193')'dnl
52 `F(`C',D,A,B,Xe,17,`0xa679438e')'dnl
53 `F(`B',C,D,A,Xf,22,`0x49b40821')'dnl
54 `G(`A',B,C,D,X1,5,`0xf61e2562')'dnl
55 `G(`D',A,B,C,X6,9,`0xc040b340')'dnl
56 `G(`C',D,A,B,Xb,14,`0x265e5a51')'dnl
57 `G(`B',C,D,A,X0,20,`0xe9b6c7aa')'dnl
58 `G(`A',B,C,D,X5,5,`0xd62f105d')'dnl
59 `G(`D',A,B,C,Xa,9,`0x02441453')'dnl
60 `G(`C',D,A,B,Xf,14,`0xd8a1e681')'dnl
61 `G(`B',C,D,A,X4,20,`0xe7d3fbc8')'dnl
62 `G(`A',B,C,D,X9,5,`0x21e1cde6')'dnl
63 `G(`D',A,B,C,Xe,9,`0xc33707d6')'dnl
64 `G(`C',D,A,B,X3,14,`0xf4d50d87')'dnl
65 `G(`B',C,D,A,X8,20,`0x455a14ed')'dnl
66 `G(`A',B,C,D,Xd,5,`0xa9e3e905')'dnl
67 `G(`D',A,B,C,X2,9,`0xfcefa3f8')'dnl
68 `G(`C',D,A,B,X7,14,`0x676f02d9')'dnl
69 `G(`B',C,D,A,Xc,20,`0x8d2a4c8a')'dnl
70 `H(`A',B,C,D,X5,4,`0xfffa3942')'dnl
71 `H(`D',A,B,C,X8,11,`0x8771f681')'dnl
72 `H(`C',D,A,B,Xb,16,`0x6d9d6122')'dnl
73 `H(`B',C,D,A,Xe,23,`0xfde5380c')'dnl
74 `H(`A',B,C,D,X1,4,`0xa4beea44')'dnl
75 `H(`D',A,B,C,X4,11,`0x4bdecfa9')'dnl
76 `H(`C',D,A,B,X7,16,`0xf6bb4b60')'dnl
77 `H(`B',C,D,A,Xa,23,`0xbebfbc70')'dnl
78 `H(`A',B,C,D,Xd,4,`0x289b7ec6')'dnl
79 `H(`D',A,B,C,X0,11,`0xeaa127fa')'dnl
80 `H(`C',D,A,B,X3,16,`0xd4ef3085')'dnl
81 `H(`B',C,D,A,X6,23,`0x04881d05')'dnl
82 `H(`A',B,C,D,X9,4,`0xd9d4d039')'dnl
83 `H(`D',A,B,C,Xc,11,`0xe6db99e5')'dnl
84 `H(`C',D,A,B,Xf,16,`0x1fa27cf8')'dnl
85 `H(`B',C,D,A,X2,23,`0xc4ac5665')'dnl
86 `I(`A',B,C,D,X0,6,`0xf4292244')'dnl
87 `I(`D',A,B,C,X7,10,`0x432aff97')'dnl
88 `I(`C',D,A,B,Xe,15,`0xab9423a7')'dnl
89 `I(`B',C,D,A,X5,21,`0xfc93a039')'dnl
90 `I(`A',B,C,D,Xc,6,`0x655b59c3')'dnl
91 `I(`D',A,B,C,X3,10,`0x8f0ccc92')'dnl
92 `I(`C',D,A,B,Xa,15,`0xffeff47d')'dnl
93 `I(`B',C,D,A,X1,21,`0x85845dd1')'dnl
94 `I(`A',B,C,D,X8,6,`0x6fa87e4f')'dnl
95 `I(`D',A,B,C,Xf,10,`0xfe2ce6e0')'dnl
96 `I(`C',D,A,B,X6,15,`0xa3014314')'dnl
97 `I(`B',C,D,A,Xd,21,`0x4e0811a1')'dnl
98 `I(`A',B,C,D,X4,6,`0xf7537e82')($1+A)')
100 define(`part2', `--------')
101 define(`O', `OO(E(`($1&0x000f0000)>>16'), E(`(($1>>16)&0xf000)>>12',16))')
102 define(`OO', `ifelse(E(len(defn(`part1')) < max), 1, `N(`part1', defn(
103   `part1')E($1, 16))')ifelse(substr(part2, $1, 1), `-', `N(`part2', substr(
104   part2, 0, $1)`$2'substr(part2, incr($1)))')ifelse(len(ifelse(defn(`only'),
105   1, `defn(`part1')', `translit(defn(`part2'), `-')')), 'max`, `pushdef(`do')',
106   `output(1, `found so far: 'part1 part2)-')')
107 define(`M', `ifelse(E(`$1&0x00f0ffff'),0,`O($1)')')
108 define(`rename', `define(`$2', defn(`$1'))popdef(`$1')')
109 define(`do'start, `output(1, `...'decr($1))rename(`$0', `do'E(`$1+999'))do($@)')
110 define(`do', `M(md5(`$1'))ifdef(`$0$1',`$0$1',`$0')(incr(`$1'))')
111 do(start)
113 divert`'part1
114 part2