1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day19.input] day19.m4
4 include(`intcode.m4')ifelse(intcode(19), `ok', `',
5 `errprint(`Missing IntCode initialization
9 define(`deployed', `0')
11 define(`count', `define(`deployed', incr(deployed))ifelse($1, 1,
12 `define(`killed', incr(killed))')')
19 # 0,0 is always on, but the rest of the beam might be discontinuous
21 # Sweep diagonally to find tip
22 define(`write', `count($1)define(`data', $1)')
26 define(`loop', `ifelse(data, 1, `define(`tipx', x)define(`tipy', y)',
27 `ifelse(x, 0, `define(`x', incr(y))define(`y', 0)',
28 `define(`x', decr(x))define(`y', incr(y))')try(x, y)loop()')')
30 # Sweep left edge from tip
33 define(`write', `count($1)ifelse($1, 1, `pushdef(`l', x)define(`y', incr(y))',
34 `define(`x', incr(x))')')
35 define(`loop', `ifelse(y, 50, `', `ifelse(x, 50,
36 `pushdef(`l', x)define(`y', incr(y))', `try(x, y)')loop()')')
38 # Sweep right edge from tip
41 define(`write', `count($1)ifelse($1, 0, `pushdef(`r', x)define(`y', incr(y))',
42 `define(`x', incr(x))')')
43 define(`loop', `ifelse(y, 50, `', `ifelse(x, 50,
44 `pushdef(`r', x)define(`y', incr(y))', `try(x, y)')loop()')')
46 define(`coursex', eval(l - tipx))
47 define(`coursey', eval(y - tipy))
48 forloop_arg(tipy, 49, `define(`part1',
49 eval(part1 + r - l))popdef(`l', `r')done')
50 define(`part1d', deployed)
51 define(`part1k', killed)
53 # Sweep left edge, and check diagonal of square
54 define(`x', eval(tipx + 99 / coursex))
55 define(`y', eval(tipy + 99))
56 define(`write', `count($1)define(`data', $1)')
57 define(`loop', `try(eval(x + coursex), eval(y + coursey))ifelse(data, 1,
58 `try(eval(x + coursex + 99), eval(y + coursey - 99))ifelse(data, 1,
59 `oneshot(`loop')', `define(`y', eval(y + coursey))define(`x',
60 eval(x + coursex))')', `define(`x', incr(x))')loop()')
62 define(`loop', `try(x, y)ifelse(data, 1, `try(eval(x + 99),
63 eval(y - 99))ifelse(data, 1, `oneshot(`loop')', `define(`y', incr(y))')',
64 `define(`x', incr(x))')loop()')
66 define(`part2', eval((x * 10000) + y - 99))
68 divert`'part1`'ifelse(verbose, 0, `', ` (part1k / part1d)')
69 part2`'ifelse(verbose, 0, `', ` (killed / deployed)')