day 25 optimize and improve heuristics
[aoc_eblake.git] / 2019 / day11.m4
blob8e0980fcf028d6b78fbe9c3f24be706ad9e3c79b
1 divert(-1)dnl -*- m4 -*-
2 # Usage: m4 [-Dfile=day11.input] day11.m4
4 include(`intcode.m4')ifelse(intcode(11), `ok', `',
5 `errprint(`Missing IntCode initialization
6 ')m4exit(1)')
8 parse(input)
9 define(`write', `define(`data', $1)')
10 define(`done', `define(`repeat')')
11 define(`min', `ifelse(eval($1 < min$1), 1, `define(`min$1', $1)')')
12 define(`max', `ifelse(eval($1 > max$1), 1, `define(`max$1', $1)')')
13 define(`offset', 1000)
14 define(`visit', `_$0($1, eval($2 + offset), eval($3 + offset), $4)')
15 define(`_visit', `ifdef(`g$1_$2_$3', `', `define(`count',
16   incr(count))')define(`g$1_$2_$3', $4)')
17 define(`g', defn(`visit'))
18 define(`_g', `ifdef(`g$1_$2_$3', `g$1_$2_$3', 0)')
20 # Loop until done, expect read then two writes, then pause before any read
21 # (expectations are a stack, create them in reverse order)
22 define(`loop', `
23   oneshot(`io', defn(`pause_after_write'))
24   oneshot(`io', defn(`run_after_read'))
25   run(pc)
26   visit($1, x, y, data)
27   oneshot(`io', defn(`pause_on_read'))
28   oneshot(`io', defn(`run_after_write'))
29   run(pc)
30   define(`d', eval((ifelse(data, 0, 3, 1) + d) % 4))
31   ifelse(d, 0, `define(`y', decr(y))min(`y')',
32          d, 1, `define(`x', incr(x))max(`x')',
33          d, 2, `define(`y', incr(y))max(`y')',
34          `define(`x', decr(x))min(`x')')
35   repeat($1)')
37 define(`try', `
38   save()
39   define(`x', 0)
40   define(`y', 0)
41   define(`minx', 0)
42   define(`maxx', 0)
43   define(`miny', 0)
44   define(`maxy', 0)
45   define(`count', 0)
46   define(`d', 0)
47   visit($1, 0, 0, $1)
48   define(`read', `g($1, x, y)')
49   define(`repeat', `loop($1)')loop($1)
50   restore()')
51 try(0)
52 define(`part1', count)
53 try(1)
54 include(`ocr.m4')
55 define(`char', `forloop('miny`, 'maxy`, `_$0($1, ', `)')')
56 define(`_char', `forloop($1, eval($1+4), `ifelse(g(1, ', `, $2), 1,
57   ``X'', `` '')')')
58 define(`part2', forloop(0, eval((maxx - minx - 4)/5),
59   `ocr(char(eval('minx`+1+', `*5)))'))
61 divert`'part1
62 part2