1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day24.input] [-Dhashsize=H] [-Dverbose=V] \
3 # [-Dmemoize=1] day24.m4
5 include(`common.m4')ifelse(common(24, 65537), `ok', `',
6 `errprint(`Missing common initialization
8 ifdef(`memoize', `', `ifelse(eval(defn(`foundhash') + 0 > 65536), 1,
9 `define(`memoize', 1)')')
11 define(`width', eval(150*4))define(`offset', eval(width*150))define(`part1', 0)
12 define(`list', translit(include(defn(`file')), nl, `r'))
13 define(`reset', `define(`x', 'offset`)')
15 define(`n_', `define(`dir1', `N')')
16 define(`s_', `define(`dir1', `S')')
17 define(`e_', `dir(defn(`dir1')`E')')
18 define(`w_', `dir(defn(`dir1')`W')')
19 define(`dir', `dir$1()popdef(`dir1')')
20 define(`dirE', `define(`x', incr(incr(x)))')
21 define(`dirSE', `define(`x', eval(x + 1 - 'width`))')
22 define(`dirSW', `define(`x', eval(x - 1 - 'width`))')
23 define(`dirW', `define(`x', decr(decr(x)))')
24 define(`dirNW', `define(`x', eval(x - 1 + 'width`))')
25 define(`dirNE', `define(`x', eval(x + 1 + 'width`))')
26 define(`r_', `flip(x)reset()')
27 define(`flip', `define(`t$1', ifdef(`t$1', `ifelse(t$1, 0, 1, 0)',
28 `pushdef(`tiles', `$1')1'))')
30 patsubst(defn(`list'), `.', `\&_()')
32 define(`split', `ifelse($1, 1, `$2_()', `$0(eval($1/2), substr(`$2', 0,
33 eval($1/2)))$0(eval($1-$1/2), substr(`$2', eval($1/2)))')')
34 split(len(defn(`list')), defn(`list'))
36 define(`prune', `ifelse(t$1, 0, `popdef(`tiles')popdef(`t$1')',
37 `define(`part1', incr(part1))')')
38 stack_foreach(`tiles', `prune')
39 define(`whiledef', `ifdef(`$1', `$2($1)popdef(`$1')$0($@)')')
40 define(`bump', `define(`c$1', ifdef(`c$1', `c$1', `pushdef(`near', `$1')')-)')
41 ifelse(defn(`memoize'), 1, `
42 output(1, `using memoized neighbor lookup')
43 define(`bumpall', `ifdef(`b$1', `', `getb($1, ''width``)')b$1()')
44 define(`getb', `define(`b$1', `bump($1)bump('incr(incr($1))`)bump('eval(
45 $1 + 1 - $2)`)bump('eval($1 - 1 - $2)`)bump('decr(decr($1))`)bump('eval(
46 $1 - 1 + $2)`)bump('eval($1 + 1 + $2)`)')')
48 output(1, `using dynamic neighbor lookup')
49 define(`bumpall', `bump($1)bump(incr(incr($1)))bump(eval(
50 $1 + 1 - 'width`))bump(eval($1 - 1 - 'width`))bump(decr(decr($1)))bump(
51 eval($1 - 1 + 'width`))bump(eval($1 + 1 + 'width`))')
53 define(`adjust', `ifelse(c$1, --, `pushdef(`tiles', `$1')define(`t$1', 1)',
54 c$1`'t$1, ---1, `pushdef(`tiles', `$1')', `popdef(`t$1')')popdef(`c$1')')
55 define(`day', `whiledef(`tiles', `bumpall')whiledef(`near', `adjust')')
56 forloop_arg(1, 100, `day')
58 define(`part2', len(stack_foreach(`tiles', `count')))