day 12 cover one more case
[aoc_eblake.git] / 2020 / day24.m4
blob407ad4aaee384d50de84e582b9259a9f7b504d4e
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
7 ')m4exit(1)')
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`)')
14 reset()
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'))')
29 ifdef(`__gnu__', `
30   patsubst(defn(`list'), `.', `\&_()')
31 ',`
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)`)')')
47 ', `
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')
57 define(`count', `-')
58 define(`part2', len(stack_foreach(`tiles', `count')))
60 divert`'part1
61 part2