1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dhashsize=H] [-Dfile=day18.input] day18.m4
3 # Optionally use -Dverbose=1 to see some progress
5 include(`common.m4')ifelse(common(18, 1000003), `ok', `',
6 `errprint(`Missing common initialization
11 define(`input', translit(include(defn(`file')), `.|#'nl, `0123'))
12 define(`width', incr(index(defn(`input'), 3)))
13 define(`prep', `define(`g$1', 0)define(`g'eval('width*width`+$1), 0)')
14 forloop_arg(0, width, `prep')
15 define(`prep', `_$0($1, len(translit($1, 02)), len(translit($1, 01)))')
16 define(`_prep', `define(`r0$1', $0_(eval(`$2>=3'), 1, `$'1, 1, 0))define(
17 `r1$1', $0_(eval(`$3>=3'), 1, `$'1, 2, 1))define(`r2$1', $0_(eval(`$2*$3'),
19 define(`_prep_', `ifelse($1, $2, ``pushdef(`M', `define(`g$3', $4)')'$4', $5)')
20 forloop(0, eval(9*27*27-1), `prep(eval(', `, 3, 8))')
22 define(`x', incr(width))
23 define(`visit', `ifelse($2, 3, `define(`g$1', 0)define(`n$1', 000000000)',
24 `define(`g$1', $2)define(`n$1', _$0($1)_$0(eval($1-''width``))_$0(
25 eval($1+''width``)))')define(`x', incr($1))')
26 define(`_visit', ``g$1`'g'decr($1)``'g'incr($1)``''')
28 patsubst(defn(`input'), `.', `visit(x, \&)')
30 define(`chew', `ifelse($1, 1, `visit(x, $2)', `$0(eval($1/2), substr(
31 `$2', 0, eval($1/2)))$0(eval($1-$1/2), substr(`$2', eval($1/2)))')')
32 chew(len(defn(`input')), defn(`input'))
35 define(`m', `ifdef(`M', `M()popdef(`M')m()')')
36 define(`round', `ifdef(`count$1', `count$1', `count')($1, forloop_arg(
37 'incr(width)`, 'eval(width*width-1)`, `_$0')m())')
38 define(`_round', `first(`r'n$1`($1)')')
39 define(`rename', `define(`$2', defn(`$1'))popdef(`$1')')
40 define(`count10', `define(`part1', eval(len(translit($2, 02)) *
41 len(translit($2, 01))))count($@)')
42 define(`countend', `define(`part2', eval(len(translit($2, 02)) *
43 len(translit($2, 01))))')
44 define(`count100', `output(1, `...$1')rename(`$0',
45 `count'eval($1+100))count($@)')
46 define(`count', `ifdef(`h$2', `_$0($1, eval($1-h$2))',
47 `define(`h$2', $1)')round(incr($1))')
48 define(`_count', `output(1, `cycle of $2 found at $1')rename(`countend',
49 `count'eval($1+rem(sub64(1000000000, $1), $2)))pushdef(`$0')')
50 define(`bits', `_$0(eval($1, 2))')
51 define(`_bits', ifdef(`__gnu__', ``shift(patsubst($1, ., `, \&'))'',
52 ``ifelse(len($1), 1, `$1', `substr($1, 0, 1),$0(substr($1, 1))')''))
53 define(`bits64', `ifelse(eval(len($1) < 10), 1, `bits($1)', `_$0(mul64($1,
54 5)), eval(substr($1, decr(len($1))) & 1)')')
55 define(`_bits64', `bits64(substr($1, 0, decr(len($1))))')
56 define(`rem', `_$0(0, $2, bits64($1))')
57 define(`_rem', `ifelse($1$3, 0, $2, $3, `', $1, `$0(eval(($1*2+$3)%$2), $2,
58 shift(shift(shift($@))))')')