1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Diter=N] [-Dfile=day18.input] [-Dhashsize=H] day18.m4
3 # Optionally use -Dverbose=1 to see some progress
5 include(`common.m4')ifelse(common(18, 65537), `ok', `',
6 `errprint(`Missing common initialization
9 # Operate 6 cells per int, requiring 17*102 ints to represent 100*100 cells
10 ifdef(`iter', `', `define(`iter', 100)')
11 define(`grid', translit(include(defn(`file')), `.#'nl, `01;'))
13 patsubst(defn(`grid'), `\([^;]*\);', `pushdef(`row', `\1')')
15 define(`half', `eval($1/100/2*100)')
16 define(`split', `ifelse($1, 100, `pushdef(`row', `$2')', `$0(half($1),
17 substr(`$2', 0, half($1)))$0(eval($1-half($1)), substr(`$2', half($1)))')')
18 split(eval(len(defn(`grid'))/101*100), translit(defn(`grid'), `;'))
20 define(`prep', `define(`c$1_0', 0)define(`c$1_101', 0)')
21 forloop_arg(0, 16, `prep')
22 define(`visit', `forloop(1, 100, `_$0$3(`$1', ', `)$2')')
23 define(`_visit', `forloop(0, 16, `$1(', `, `$2')')')
24 define(`_visit1', `forloop(0, 16, `$1(', `,`$2','decr(`$2')`,'incr(`$2')`)')')
25 define(`_visit2_', ``$2$3(`$1', `$2$4', 'decr(`$1')`, 'incr(`$1')`)'')
26 define(`_visit2', `$1_0(0, `$2', 1)'forloop(1, 15, `_visit2_(',
27 `, `$', `1', `2')')`$1_16(16, `$2', 15)')
28 define(`prep', `define(`c$1_$2', eval(`0x'substr(0row`'0, eval($1 * 6), 6)0))')
29 visit(`prep', `popdef(`row')')
31 define(`near', `define(`n$1_$2', _near((c$1_$3+c$1_$2+c$1_$4)))')
32 define(`_near', `eval(`($1<<4)+$1+($1>>4)')')
33 define(`set_0', `_set(`$1', `$2', eval((n$1_$2-c$1_$2
34 +(n$3_$2>>24))|c$1_$2), `0x00111110')')
35 define(`set_16', `_set(`$1', `$2', eval((n$1_$2-c$1_$2
36 +(n$3_$2<<24))|c$1_$2), `0x01111100')')
37 define(`set', `_$0(`$1', `$2', eval((n$1_$2-c$1_$2+(n$3_$2<<24)
38 +(n$4_$2>>24))|c$1_$2), `0x01111110')')
39 define(`_set', `define(`c$1_$2',
40 eval(`$3&($3>>1)&(~(($3>>2)|($3>>3)))&$4'))')
41 define(`round', `ifelse($1, 'iter`, `', `ifelse(index($1, 0), -1, `',
42 `output(1, $1)')visit(`near', `', `1')visit(`set', `', `2')$2`'$0(incr($1),
44 define(`count', `len(translit(visit(`_$0'), 0))')
45 define(`_count', `eval(c$1_$2, 16)')
47 define(`push', `pushdef(`c$1_$2', defn(`c$1_$2'))')
50 define(`part1', count)
51 define(`pop', `popdef(`c$1_$2')')
53 define(`stuck', `define(`c0_1', eval(c0_1`|0x00100000'))define(`c16_1',
54 eval(c16_1`|0x00000100'))define(`c0_100',
55 eval(c0_100`|0x00100000'))define(`c16_100', eval(c16_100`|0x00000100'))')
58 define(`part2', count)