Compare commits
	
		
			1 Commits
		
	
	
		
			main
			...
			hackerrank
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a5ebbe25d0 | 
@ -1,11 +0,0 @@
 | 
				
			|||||||
...........
 | 
					 | 
				
			||||||
.....###.#.
 | 
					 | 
				
			||||||
.###.##..#.
 | 
					 | 
				
			||||||
..#.#...#..
 | 
					 | 
				
			||||||
....#.#....
 | 
					 | 
				
			||||||
.##..S####.
 | 
					 | 
				
			||||||
.##..#...#.
 | 
					 | 
				
			||||||
.......##..
 | 
					 | 
				
			||||||
.##.#.####.
 | 
					 | 
				
			||||||
.##..##.##.
 | 
					 | 
				
			||||||
...........
 | 
					 | 
				
			||||||
@ -1,131 +0,0 @@
 | 
				
			|||||||
...................................................................................................................................
 | 
					 | 
				
			||||||
.#.......#..#...#.......#......#....#..#...#...#....#.#..........................................#...............#..........#......
 | 
					 | 
				
			||||||
.............##..................#......#.#....#.......................##..#........................#......#..........#............
 | 
					 | 
				
			||||||
......#..........................#....#.....#.............#................##....#.#.............#.........#.##...........#........
 | 
					 | 
				
			||||||
.#................#............................#...........................#..##.....#..................#..##..#.#.........##......
 | 
					 | 
				
			||||||
.....#.............#.....##.............##..........#...........#.............#.....#...........#.#.......#....#......#..........#.
 | 
					 | 
				
			||||||
........#....................#....#.#.#......##........#...........#...........#..........#...#..........#......................#..
 | 
					 | 
				
			||||||
.........#.#...#.......#........#........##...#...#..##........................................##...#.#........................#...
 | 
					 | 
				
			||||||
......#.....#..#..#.#..#..............#...#..#.....#...........#.....#........#.#...........#...........#.#...............#.....#..
 | 
					 | 
				
			||||||
...........#.......####..#.#..............##................#.#.#.....................##.....................#...#..............#..
 | 
					 | 
				
			||||||
......###...#......#................##...#...#....#...........#...#..............#.........#..#..................................#.
 | 
					 | 
				
			||||||
...............#..##..........#...........................##......#.##.........................#..#.#...........#.#...........#....
 | 
					 | 
				
			||||||
...##........#...#...#...##...##...........#..#...................#...................#.#..#.........#.......#..#...........##...#.
 | 
					 | 
				
			||||||
................#.....#..##......#.....#.....##............#..#..........##...........................#.#.......##.....#.....#.....
 | 
					 | 
				
			||||||
.#..#.......#.#...#..##.....#............................#......#...#....#................#.#..#.....#.......##................#...
 | 
					 | 
				
			||||||
...............#.....#........................#..........#.....#..............................................#..................#.
 | 
					 | 
				
			||||||
.....#......#..........................................#....................................#..#.......#.#..#......#.#....#..##....
 | 
					 | 
				
			||||||
............##............#.......###.......................#..#....#......................................#..#.........#..........
 | 
					 | 
				
			||||||
..#...............#.....#...#...#......................#...#.#..............................#.#..#.#.....#.#.#..#....#.....#...##..
 | 
					 | 
				
			||||||
.#.............................##.................#.......#.......##....#....................#.....#.#........#.....#........#.....
 | 
					 | 
				
			||||||
.#....##...................##.....#.#..............#.#....#....#..#....#......#..........#.....##............#....#.............##.
 | 
					 | 
				
			||||||
.........#....#.....#..#.........#....#.#..........#...#...#.......#....#..##.......................#.#..#........#..#....#..#.#...
 | 
					 | 
				
			||||||
..#..................#.......#..#.#..............##.......#........#..............#.........#..#....#......#..#..........#.........
 | 
					 | 
				
			||||||
........#.....#......#.....#......#...#.......#....#.......#.#..#................#....................##.............#.......#.....
 | 
					 | 
				
			||||||
..#.................#..............#...........................................#.....#..................#...#.#..................#.
 | 
					 | 
				
			||||||
.......#......#.....#...........................#.....#..................#.....................#.....#.#......#........#.#.......#.
 | 
					 | 
				
			||||||
..#.#.#...................#...#..#................#....#.......#......................#...............#.........##...#.#.....###...
 | 
					 | 
				
			||||||
.....#...#....##....#........####...........#.................#...#...........................................#..............##....
 | 
					 | 
				
			||||||
..##.#..#.#..........#.#.#..#................................#..#.............#..#......#...........................#.##...........
 | 
					 | 
				
			||||||
..............#.............................##........#..##........................#.............................#........#........
 | 
					 | 
				
			||||||
........#.........#........#..#........#..#........#...#.#........#...........#.........................#.#..........#...#......#..
 | 
					 | 
				
			||||||
.........##.....#........#.....................#..#.............#.....#........#....................#....#.#.#......#.....#........
 | 
					 | 
				
			||||||
......................#...................####..#.........#....#.........#...........#..................#..#.................#.....
 | 
					 | 
				
			||||||
..#.........#...#.....##................##.##....#.....#....#..............................#..#.............#..#...................
 | 
					 | 
				
			||||||
..........##......#..#..............#.#....#......#................#.....#....#..............#..................#..................
 | 
					 | 
				
			||||||
.#.#..####...#....................#.#.#.....#...#...................#....#.#.....#.#.......#.#...........#......#.#................
 | 
					 | 
				
			||||||
.......#.........#..#.#..............###.......#....#.........................#.......#.###...#............#....#.#..#....###.#....
 | 
					 | 
				
			||||||
........#....#...#......#.................#..........................#.........................#...........##.............#.#......
 | 
					 | 
				
			||||||
.#..............#.....................#......#.............##............#..#..........#...................#...#....#..............
 | 
					 | 
				
			||||||
......#..#..#.#...............#........###.......#.#...........#...........#.#.........#..#.....................#......#..#.#......
 | 
					 | 
				
			||||||
.....#...............#.........#....#..........#.......#.......#......#...#..##.....#.....#........#.#.......#.......#..#...#......
 | 
					 | 
				
			||||||
..#............#.....................#...#.......#....###...........#.....#.#.................#................#.........#..##.#...
 | 
					 | 
				
			||||||
..............................#.....#..................................#.....##...............#.......#.........#.....#....##......
 | 
					 | 
				
			||||||
..#...##...#...#..............#.................##..#......#.................#....#......#...#...#......#..........................
 | 
					 | 
				
			||||||
.........#....#..............#........#..#...............#....#...#.....#..#......#.........#.......#.#..#........#...........#....
 | 
					 | 
				
			||||||
........#..#....................#.........#...##.#.#..............#......#.#..........##...##....#......................#..........
 | 
					 | 
				
			||||||
.##..#....#....#.......##......#............#..#......#.....##..................#####..#...#......#.#...#..........#.#.....#..#....
 | 
					 | 
				
			||||||
..#...........#....................#.......#......#.........#...............#......#........##........#.................#.....#.#..
 | 
					 | 
				
			||||||
..#....#.#...............#.#.........................#.............####..............................##................###.........
 | 
					 | 
				
			||||||
.....#.......................................#....#...##...#.......#.......#.....#.##..##.................#.....................##.
 | 
					 | 
				
			||||||
.........#...........#..#..##.#..........#..#.........#..#.....#...................................##....#...............#..#.#....
 | 
					 | 
				
			||||||
.....#..#...........##............#........#..................#............#..........#..........#..#...........#..................
 | 
					 | 
				
			||||||
............................#.........#...............#..................#.#....#.#..#........#.....#...........#...........#......
 | 
					 | 
				
			||||||
................#...##.#....#..##..........#.#........##.#..#..#.....................#....#.................#.#...............#....
 | 
					 | 
				
			||||||
.#.....#..............#.#..........#..#........#...............#..#.#..##..#.#.#.........................#.................#.......
 | 
					 | 
				
			||||||
....#..............#................#.....#..#.......#..#.#.........#..........#..........#.....#..........##.....#............#...
 | 
					 | 
				
			||||||
..............##...........#.......#......#..................#.......#.....#.#...#...............#.#........#......#............#..
 | 
					 | 
				
			||||||
................#.....#....#........#....#.......#.#.##.....#...#..#.##...#................#.#.....#....#.............#............
 | 
					 | 
				
			||||||
...........#.#.##..####.....#....#.#...#.#...........#...#.......................#.#....#.....#..#................###..............
 | 
					 | 
				
			||||||
...................#....#..........#.#..##.....#..#..#......###............#..#...........#....#......#............................
 | 
					 | 
				
			||||||
...........................................#.......#..............#.##.......##.......#...#.....#.#..#.....#..###..................
 | 
					 | 
				
			||||||
............###........#.......#.#....#.....#....#..#........#.........##....#.....#..........#......#............#..#.#...........
 | 
					 | 
				
			||||||
............#..........#................##.#..............#.....#................#....................................#..#.........
 | 
					 | 
				
			||||||
...........#.....#.....................#...#.....#.......#..........#....#.....###.....##.#.##.#.....#......#......#.......#.......
 | 
					 | 
				
			||||||
.....................#..#.....#...##.....#..#...........#....#....##............##.................##............##................
 | 
					 | 
				
			||||||
.................................................................S.................................................................
 | 
					 | 
				
			||||||
........#.#........#..........#.....#......#........#.#............#.#.........##...#............#...#.....#...........#.....#.....
 | 
					 | 
				
			||||||
..................##.......#......#..#..................#..##......#.........#...#.........#............#....#...........##........
 | 
					 | 
				
			||||||
..................#...........#.##.......#..............#....................#.#....#...##...#.....#.......#..#.....##.............
 | 
					 | 
				
			||||||
...........#....#....##...#................................#.........#.................#....#.......................#...#..........
 | 
					 | 
				
			||||||
.............#.#.#.....#.#...#.......#.#...........#....#.#.........#........##......#.......#.......##...#..........#.##..........
 | 
					 | 
				
			||||||
...........##.#....#....#..#.....#...............#......................#...........#.....#...........#.#.......#..................
 | 
					 | 
				
			||||||
.#.......................#.#...##.#....#.#...........#.#....##.##......#........................##....#.#....#.....................
 | 
					 | 
				
			||||||
...#..................#.#...........##....###.................#....................##......#.....#............#.##....#.......##...
 | 
					 | 
				
			||||||
.#..................####...#.#..#.##.#...####...#......#....................#..........................#....#......................
 | 
					 | 
				
			||||||
.....#..........#.....#.#...............#.........##...#......#.#.....#...........#.....#............##......#.....#...............
 | 
					 | 
				
			||||||
......#........#....#..#............................###.#...##........#........#.................#..#........#...............##....
 | 
					 | 
				
			||||||
......................#.........................##....#...#..............#..#............#.#....#......##.#......#.........##......
 | 
					 | 
				
			||||||
..................#....#...#.#.......#..............#..#..#...#.......#...#.....#.....#...............#.#.#...............#........
 | 
					 | 
				
			||||||
...#...##......................##..##...........#......#.............#............#...........##.......#....#......................
 | 
					 | 
				
			||||||
.............................##...........##...#...#.....#....#.......#.#..#.....##...............#..#.#......#..............##....
 | 
					 | 
				
			||||||
...#..#.#...#.......#..................#............#....#.#.##.#.........#......#........#..#..........#....##...........#....#...
 | 
					 | 
				
			||||||
.....#.............................#......#.#.....#.##.#.................#.........#..#..#.#.#........................#.#.......#..
 | 
					 | 
				
			||||||
....#........#........#....#.#.#.....#.##............###.#..........#...##......#........##...#.........#.............#........#...
 | 
					 | 
				
			||||||
..#..............................#.............................#......#...................#...#......#.............#...............
 | 
					 | 
				
			||||||
.......#...#...............#.................##....................#....##.......#....##....##...#..................#..............
 | 
					 | 
				
			||||||
.........................#...#..#.....##.............#...##.......#.....#...#..............#.....#.#.#..#........................#.
 | 
					 | 
				
			||||||
......#.......##.#.............#....................#...#...........#...#..##....#.....#............#...........#........#.........
 | 
					 | 
				
			||||||
...#....#...#......#........................#.....#.........#......#........#.....#.#...........#.#..............#......#....#.....
 | 
					 | 
				
			||||||
........#..........#...................#...........##.#..#...#................#....##.............#................#....#..........
 | 
					 | 
				
			||||||
........#.......#....#.............#..........#...................#.#....#.#........#..#..............................#..........#.
 | 
					 | 
				
			||||||
............#........#....................#.#.........#......#.............#................#...#.............#....#...............
 | 
					 | 
				
			||||||
..#..............................#..#....##.....#......................##...#..#.........#......#......................#...#...#.#.
 | 
					 | 
				
			||||||
.##....#.............#...........##..................#...#..............#.......#................................#.........#.......
 | 
					 | 
				
			||||||
.....#......#.#.....##...........#.....#.......#..........##..#.............#.#.........#.#.#.............##........#......#..#....
 | 
					 | 
				
			||||||
.......#.......#.#.#..#......................#....#............##....#...........#.........................#......#................
 | 
					 | 
				
			||||||
.........##.........#..............#.#.#....#...#.......#.................................#..##..................##.###.##...#.....
 | 
					 | 
				
			||||||
......................#...#.#.......#..#.#..........#........#.......#.................#..................................#........
 | 
					 | 
				
			||||||
....##........#.........#.........................#................#......#...#.....#..................................#..#.#......
 | 
					 | 
				
			||||||
...##..............#..................#...#......#........###..#.......#..........#..............................#......#..........
 | 
					 | 
				
			||||||
.#.#.#....#..........#......#.#.........#.....#...............................#.....#.#............#....#........#.............#...
 | 
					 | 
				
			||||||
........#.........#.........#......................#..#......##.....#..#..........................#......##....#......##.##.....#..
 | 
					 | 
				
			||||||
.##...#.......#.#....#..#.#...................#.........#....#...........#.....#.........#............##......#............#.......
 | 
					 | 
				
			||||||
.##..#.........#..........#.#.................................#.#.#...............................#............#......##...#.#.....
 | 
					 | 
				
			||||||
......#........#..#...#............#..............#............#......##.....#.................................#......#.#.....#....
 | 
					 | 
				
			||||||
..........#........#...........#....................................#.....#...............................#............##....#.##..
 | 
					 | 
				
			||||||
........#.............#..#......##..................#.............#..#...#.#.....#...#...............#........................#....
 | 
					 | 
				
			||||||
....#...............#..........#....#...........................#....##.##...................#.#.......#...#.##....#........##..#..
 | 
					 | 
				
			||||||
......#.....#..#..........###...#.................####.###..........#...........#..........#......#............................#...
 | 
					 | 
				
			||||||
.#...#......#........#..#............##...............#.##......#...#.....#....................#.........#............#...#........
 | 
					 | 
				
			||||||
................##...................#.##..............#...#..#.......#.......###........#..#..#........#...##.....................
 | 
					 | 
				
			||||||
..............#....#..#..#.............##..............#................................#.....#..#....###.##..............#........
 | 
					 | 
				
			||||||
..#..............#........................................#..........#.....#..................#............#..#....................
 | 
					 | 
				
			||||||
.........#...#.....#...#...##...........#.###............##...#........#......................##......#....#.......#...............
 | 
					 | 
				
			||||||
....#....#.....#.......#......................................#.#.#....#..#..#..........#...................#........#...#.........
 | 
					 | 
				
			||||||
..#..#..................#..............#...#..#.........#......#....#.#................##..........#..#................#...........
 | 
					 | 
				
			||||||
...#...................#...........#....#...#.............##...#.......#.#..........#..#...............#....#....#.............#...
 | 
					 | 
				
			||||||
.......................##.#.#..##........#....#.........#.#.#.....##..............#.......#.......##.#..........#.#................
 | 
					 | 
				
			||||||
.....#..#..................#..##....#.......#.............#...#.....#.............#.............#.#...............#.....##......##.
 | 
					 | 
				
			||||||
...#.#.....#..........#.#............#..#..........................##.............#....#.......#.#...#...#....................#.#..
 | 
					 | 
				
			||||||
............##.#............#....#....#....#..##...#...............................#...#...#.........#.......................##.##.
 | 
					 | 
				
			||||||
....#.#...............#...#.......#............#..#...........................#..............#..........#....#...#...#..#...#....#.
 | 
					 | 
				
			||||||
.......#..#..#.#..#......#..........................#...............#.........#...........#................#..#...#................
 | 
					 | 
				
			||||||
...#..#...#.....#.#.......#....................................................#........#..........#.#...#......#..........#.......
 | 
					 | 
				
			||||||
..#...#.......#..#..............#.#...#.....#...#....#............#..........##...#.........##.............#.......................
 | 
					 | 
				
			||||||
...#.............#...#....#...#.....#.#.#..............#..........#........#........##...........#..#.#......................#.....
 | 
					 | 
				
			||||||
.#.......#.................#...............#..........#.....................#.....#............#......##....#.....#...#....###.....
 | 
					 | 
				
			||||||
...##...........#..........#.#........#............#..#.#........................#.....##............#...##.#.......#.##....#......
 | 
					 | 
				
			||||||
...........#........#...........#.......#......#...#.....#............................#........#..#................#...#....##.....
 | 
					 | 
				
			||||||
...##.##.........#.####..#............#..#.....#.......................#......#..........#.#..#.#....##........#....#.....#..#..##.
 | 
					 | 
				
			||||||
...................................................................................................................................
 | 
					 | 
				
			||||||
@ -1,99 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// var log = aoc.Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() { aoc.MustResult(aoc.Runner(runner(64))) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type result struct {
 | 
					 | 
				
			||||||
	valuePT1 int
 | 
					 | 
				
			||||||
	valuePT2 int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func runner(rounds int) func(scan *bufio.Scanner) (*result, error) {
 | 
					 | 
				
			||||||
	return func(scan *bufio.Scanner) (*result, error) {
 | 
					 | 
				
			||||||
		var garden garden
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for scan.Scan() {
 | 
					 | 
				
			||||||
			txt := scan.Text()
 | 
					 | 
				
			||||||
			garden.m = append(garden.m, []rune(txt))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			for i, c := range txt {
 | 
					 | 
				
			||||||
				if c == 'S' {
 | 
					 | 
				
			||||||
					garden.start[0] = len(garden.m) - 1
 | 
					 | 
				
			||||||
					garden.start[1] = i
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		garden.Step(rounds)
 | 
					 | 
				
			||||||
		return &result{
 | 
					 | 
				
			||||||
			valuePT1: len(garden.steps[len(garden.steps)-1]),
 | 
					 | 
				
			||||||
		}, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type garden struct {
 | 
					 | 
				
			||||||
	start aoc.Point[int]
 | 
					 | 
				
			||||||
	m     [][]rune
 | 
					 | 
				
			||||||
	steps []aoc.Set[aoc.Point[int]]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (g *garden) Neighbors(p aoc.Point[int]) []aoc.Point[int] {
 | 
					 | 
				
			||||||
	var neighbors []aoc.Point[int]
 | 
					 | 
				
			||||||
	for _, n := range []aoc.Point[int]{
 | 
					 | 
				
			||||||
		{p[0] - 1, p[1]},
 | 
					 | 
				
			||||||
		{p[0] + 1, p[1]},
 | 
					 | 
				
			||||||
		{p[0], p[1] - 1},
 | 
					 | 
				
			||||||
		{p[0], p[1] + 1},
 | 
					 | 
				
			||||||
	} {
 | 
					 | 
				
			||||||
		if n[0] >= 0 && n[0] < len(g.m) && n[1] >= 0 && n[1] < len(g.m[0]) && g.m[n[0]][n[1]] != '#' {
 | 
					 | 
				
			||||||
			neighbors = append(neighbors, n)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return neighbors
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (g *garden) Step(n int) {
 | 
					 | 
				
			||||||
	if len(g.steps) == 0 {
 | 
					 | 
				
			||||||
		g.steps = append(g.steps, aoc.NewSet(g.start))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for step := range(n) {
 | 
					 | 
				
			||||||
		g.steps = append(g.steps, aoc.NewSet[aoc.Point[int]]())
 | 
					 | 
				
			||||||
		for p := range g.steps[step] {
 | 
					 | 
				
			||||||
			for _, n := range g.Neighbors(p) {
 | 
					 | 
				
			||||||
				g.steps[step+1].Add(n)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (g garden) String() string {
 | 
					 | 
				
			||||||
	var b []rune
 | 
					 | 
				
			||||||
	for i, line := range g.m {
 | 
					 | 
				
			||||||
		if i == g.start[0] {
 | 
					 | 
				
			||||||
			line[g.start[1]] = 'X'
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if steps := len(g.steps) - 1; steps > 0 {	
 | 
					 | 
				
			||||||
			for p := range g.steps[len(g.steps)-1] {
 | 
					 | 
				
			||||||
				if p[0] == i {
 | 
					 | 
				
			||||||
					line[p[1]] = 'O'
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		b = append(b, line...)
 | 
					 | 
				
			||||||
		b = append(b, '\n')
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return string(b)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,41 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/matryer/is"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed example.txt
 | 
					 | 
				
			||||||
var example []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed input.txt
 | 
					 | 
				
			||||||
var input []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestExample(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := runner(6)(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 16)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestSolution(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := runner(64)(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 3709)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,13 +0,0 @@
 | 
				
			|||||||
jqt: rhn xhk nvd
 | 
					 | 
				
			||||||
rsh: frs pzl lsr
 | 
					 | 
				
			||||||
xhk: hfx
 | 
					 | 
				
			||||||
cmg: qnr nvd lhk bvb
 | 
					 | 
				
			||||||
rhn: xhk bvb hfx
 | 
					 | 
				
			||||||
bvb: xhk hfx
 | 
					 | 
				
			||||||
pzl: lsr hfx nvd
 | 
					 | 
				
			||||||
qnr: nvd
 | 
					 | 
				
			||||||
ntq: jqt hfx bvb xhk
 | 
					 | 
				
			||||||
nvd: lhk
 | 
					 | 
				
			||||||
lsr: lhk
 | 
					 | 
				
			||||||
rzs: qnr cmg lsr rsh
 | 
					 | 
				
			||||||
frs: qnr lhk lsr
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,63 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"iter"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// var log = aoc.Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type result struct {
 | 
					 | 
				
			||||||
	valuePT1 int
 | 
					 | 
				
			||||||
	valuePT2 int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func run(scan *bufio.Scanner) (*result, error) {
 | 
					 | 
				
			||||||
	g := aoc.Graph[string, int]()
 | 
					 | 
				
			||||||
	var root string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for scan.Scan() {
 | 
					 | 
				
			||||||
		line := scan.Text()
 | 
					 | 
				
			||||||
		v, lis, ok := strings.Cut(line, ": ")
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if root == "" {
 | 
					 | 
				
			||||||
			root = v
 | 
					 | 
				
			||||||
		}	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for _, l := range strings.Split(lis, " ") {
 | 
					 | 
				
			||||||
			g.AddEdge(v, l, 1)
 | 
					 | 
				
			||||||
			g.AddEdge(l, v, 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i, v := range enumerate(g.BFS(root)) {
 | 
					 | 
				
			||||||
		fmt.Println(i, v)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &result{}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func enumerate[T any](vs iter.Seq[T]) iter.Seq2[int, T] {
 | 
					 | 
				
			||||||
	i := 0
 | 
					 | 
				
			||||||
	return func(yield func(int, T) bool) {
 | 
					 | 
				
			||||||
		for v := range vs {
 | 
					 | 
				
			||||||
			if !yield(i, v) {
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			i++
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}	
 | 
					 | 
				
			||||||
@ -1,41 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/matryer/is"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed example.txt
 | 
					 | 
				
			||||||
var example []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed input.txt
 | 
					 | 
				
			||||||
var input []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestExample(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 50)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestSolution(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 0)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
3   4
 | 
					 | 
				
			||||||
4   3
 | 
					 | 
				
			||||||
2   5
 | 
					 | 
				
			||||||
1   3
 | 
					 | 
				
			||||||
3   9
 | 
					 | 
				
			||||||
3   3
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,86 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"iter"
 | 
					 | 
				
			||||||
	"slices"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// var log = aoc.Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type result struct {
 | 
					 | 
				
			||||||
	valuePT1 int
 | 
					 | 
				
			||||||
	valuePT2 int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func run(scan *bufio.Scanner) (*result, error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		left  []int
 | 
					 | 
				
			||||||
		right []int
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for scan.Scan() {
 | 
					 | 
				
			||||||
		txt := scan.Text()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var l, r int
 | 
					 | 
				
			||||||
		_, err := fmt.Sscanf(txt, "%d %d", &l, &r)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		left = append(left, l)
 | 
					 | 
				
			||||||
		right = append(right, r)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sort.Ints(left)
 | 
					 | 
				
			||||||
	sort.Ints(right)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result := &result{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result.valuePT1 = aoc.Reduce(func(i int, z pair[int, int], sum int) int {
 | 
					 | 
				
			||||||
		return sum + aoc.ABS(z.L-z.R)
 | 
					 | 
				
			||||||
	}, 0, zip(slices.Values(left), slices.Values(right)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rmap := aoc.Reduce(func(i int, z int, m map[int]int) map[int]int {
 | 
					 | 
				
			||||||
		m[z]++
 | 
					 | 
				
			||||||
		return m
 | 
					 | 
				
			||||||
	}, make(map[int]int), slices.Values(right))
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	for _, v := range left {
 | 
					 | 
				
			||||||
		if r, ok := rmap[v]; ok {	
 | 
					 | 
				
			||||||
			result.valuePT2 += v*r
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return result, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type pair[L, R any] struct {
 | 
					 | 
				
			||||||
	L L
 | 
					 | 
				
			||||||
	R R
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func zip[L, R any](l iter.Seq[L], r iter.Seq[R]) iter.Seq[pair[L,R]] {
 | 
					 | 
				
			||||||
	return func(yield func(pair[L, R]) bool) {
 | 
					 | 
				
			||||||
		pullR, stop := iter.Pull(r)
 | 
					 | 
				
			||||||
		defer stop()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for l := range l {
 | 
					 | 
				
			||||||
			r, _ := pullR()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if !yield(pair[L, R]{L: l, R: r}) {
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,41 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/matryer/is"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed example.txt
 | 
					 | 
				
			||||||
var example []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed input.txt
 | 
					 | 
				
			||||||
var input []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestExample(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 11)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 31)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestSolution(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 2756096)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 23117829)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
7 6 4 2 1
 | 
					 | 
				
			||||||
1 2 7 8 9
 | 
					 | 
				
			||||||
9 7 6 2 1
 | 
					 | 
				
			||||||
1 3 2 4 5
 | 
					 | 
				
			||||||
8 6 4 4 1
 | 
					 | 
				
			||||||
1 3 6 7 9
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,88 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// var log = aoc.Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type result struct {
 | 
					 | 
				
			||||||
	valuePT1 int
 | 
					 | 
				
			||||||
	valuePT2 int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func run(scan *bufio.Scanner) (*result, error) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sum := 0
 | 
					 | 
				
			||||||
	sum2 := 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for scan.Scan() {
 | 
					 | 
				
			||||||
		txt := scan.Text()
 | 
					 | 
				
			||||||
		row := aoc.ReadStringToInts(strings.Fields(txt))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		good, bad := testSafety(row)
 | 
					 | 
				
			||||||
		if good {
 | 
					 | 
				
			||||||
			sum++
 | 
					 | 
				
			||||||
			sum2++
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for i := max(0, bad-1); i < min(bad+2, len(row)); i++ {
 | 
					 | 
				
			||||||
			arr := cut(i, row)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			good, _ := testSafety(arr)
 | 
					 | 
				
			||||||
			if good {
 | 
					 | 
				
			||||||
				sum2++
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &result{valuePT1: sum, valuePT2: sum2}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func testSafety(row []int) (bool, int) {
 | 
					 | 
				
			||||||
	good := true
 | 
					 | 
				
			||||||
	bad := -1
 | 
					 | 
				
			||||||
	increasing := false
 | 
					 | 
				
			||||||
	decreasing := false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i, v := range row[1:] {
 | 
					 | 
				
			||||||
		if v > row[i] {
 | 
					 | 
				
			||||||
			increasing = true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if v < row[i] {
 | 
					 | 
				
			||||||
			decreasing = true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if difference := aoc.ABS(v - row[i]); difference < 1 || difference > 3 {
 | 
					 | 
				
			||||||
			good = false
 | 
					 | 
				
			||||||
			bad = i
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if increasing && decreasing {
 | 
					 | 
				
			||||||
			good = false
 | 
					 | 
				
			||||||
			bad = i
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return good, bad
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func cut(i int, values []int) []int {
 | 
					 | 
				
			||||||
	arr := make([]int, 0, len(values))
 | 
					 | 
				
			||||||
	arr = append(arr, values[:i]...)
 | 
					 | 
				
			||||||
	arr = append(arr, values[i+1:]...)
 | 
					 | 
				
			||||||
	return arr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,43 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/matryer/is"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed example.txt
 | 
					 | 
				
			||||||
var example []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed input.txt
 | 
					 | 
				
			||||||
var input []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestExample(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 2)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 4)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestSolution(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 486)
 | 
					 | 
				
			||||||
	is.True(result.valuePT2 > 517)
 | 
					 | 
				
			||||||
	is.True(result.valuePT2 > 523)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 540)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
)+when())~why(),),mul(712,171)@}-?}mul(506,85)who()%mul(613,601)/;#from()#mul(977,581)~what()?/$^-+(*mul(142,89)[who();*):*mul(64,644)}when()select()mul(652,872)mul(594,202)?%$when(196,699)mul(311,646)<>/how()where()(+:mul(867,971)}&where()'/&[&$mul(192,659)select();<#}mul(367,411)mul(841,862)when()(%!mul(922,272)^;}mul(593,223)mul(918,232)mul(760,145)]^?why()>mul(558,476)where()who()&do()^]($,~&-{where()mul(855,134),(--{mul(691,389)+mul(352,712)why()<(]'/}-mul(138,405)$where()mul(176,679) from()'!why(){:mul(516,55)%*>mul(97,636)mul(30,945)**~what()$,mul(486,399)# ,~~!]mul(277,667);~$[from()how()&mul(412,36)([@@,what()% mul(478,68)&mul(293,979)mul(218,379)~)'?-&from()@mul(887,161)(mul(156,481)who();&[:mul(308,96)mul(718,985),] when())/~>^$mul(84,469)*<where()how()[mul(257,600)<~mul(660,909)select()mul(510,180)what()mul(619,634)#mul(721,403)why()@!,~:>where()mul(500,291)who()])]*don't()who()select()^;,@mul(837,399)$(,(-who()}'mul(835,602)~:]mul(99,872)how()what()<select()how()(don't()[[@, ,mul(962,879)who()])mul(828,134)$where()when())>%{who(794,618)>mul(227,398)why()where()-why()what()^/:; mul(753,183)[{ ]#^#%%~mul(196,63)}%don't()who()$ :how(),select()~@mul(214,483),:select()%)}who()mul(198,36)*do()what()mul(330,804)what():+>mul(10,447)*/!mul(580,733):&where()'mul(247,9)$)[:#-select()?do()mul(157,768)why()/ who()$from()where()don't()mul(527,694){how(206,792)mul(314,331)/from()/what()#mul(49,792)',-(why()#/]mul(645,190)from()$?mul(775,2)!+select()+^]from(104,329)!mul(287,711)}select():){mul(770,682)!don't()! *^+ when()]%-mul(291,143)mul(956,213)[[>{%'#*{~mul(569,514)[}how()@;mul(291,643)what()%&-where()#@<mul(729,139){^mul(501,801)]mul(261,648)}+~>when()mul(678,494)>%mul(303?<%where()what()mul(601,775)mul(91,748)&why()mul(648,173)~*mul(101,949)*:}>'from()-what()^}mul(890,865)what()mul(398,428),select(261,665)where()when()+mul(315,619what()mul(301,311)^~ where(297,851)#{!+&:mul(548,329)mul(239,714)who()@why()(#+!select()why()do()when()mul(249,859)}<select()&mul(239,140{from(149,864)]#]*~ mul(382,788)select(519,600)select(),from()(mul(350,980)@([-,~~%select()mul(710,125)what()how()]-/where()from()%mul(621,643)+what()~!how()what(814,400)<>>@mul(174,437)how(131,486)mul(294,93)mul(605,381)@#}what():~mul(873,431)#)who()^<why()mul(463,819);mul(961,13)what()why(474,300)@}&!]mul(507,494)/@}mul(636,958)^ ~from();!where()how()mul(801,95#; ;<when()who()*(mul(539,800))don't()mul(361,163)>how()select()from()#mul(411,803)-(>why(){{mul(400,846)mul(705(~+%mul(235,314)how(),where()++<{mul(795,270)how()#? $'*select()mul(301,531)mul(109,954)/mul(451,416)%%!select()mul(834,747)%select()[ mul(457,765)do()when()@<!how()mul(520,202):where(41,552)!'&@-,$mul(493,844)-?'*what()when()<^mul(937,957)who()where()who()mul(301,646)/^select()#;how()}select()mul(954,724)mul(695,132))*%mul(976,455)when()**from()]what()@how()')mul(492,975);what();^''#/?~mul(258,829)#*how()#>mul(779,58)('who()mul(275,708)
 | 
					 | 
				
			||||||
])$&mul(546,476)&]mul<}~mul(490,931) why()>~)from()@mul(302,82)mul(625,374)-;>%where()mul(864,633):!-,how()when()mul(748,5)what()!how(447,20)]what()/where()<'}don't()from()}why()mul(837,78)what()&:%where()?mul(402,690)mul(689,472)(:{+&}*+mul(915,883)}?)#from(62,762)-mul(512,958)+who()$#^{*mul(798,476{:@who()#mul(89,309),how()!what()what()where()mul(613,761)^[~~:&do()>mul(375,874))?{why()'@mul(75,714)!<%why():!don't()select()?when()@:?<[~mul(43,740)mul(389,134{'(~- >who()mul(755,490)when() what()mul(391,722);what()mul(107,927)~mul(901,762)+;when()+$^select()mul(609,510)#how():select()@)mul(937,386)) +&){mul(757,236)?how()/[who()'*how(937,357)&when()mul(521,787)where(954,730)#what()^mul(158,498)+mul']do() select()}$mul(60,389):~/;;#where()^mul(958,451)*!{{ %/#:mul(855,921)]mul(558,622))-mul(269,240)+how(626,93)+,$(!mul(735,376)%%[where()mul(868,976)~& @;]mul(597,168)from()what()select()@what()mul(40,231):who()({&who()~don't()+~who()-mul(693,922)/why()mul(597,656)mul(826,321)when()mul(793,429)select()~:~}how()how()@mul(837,77)when()mul(389,114)@mul(362,967)+mul(342,929)#where()~mul(218,879)--+[%]who(933,163)mul(314,457)'&/&,)(mul(362,966)<?]^~mul(179,657) do()!from(898,248)?:where()<when() ~when()mul(512,132)(@$?when()$how()@how(50,144)mul(570,592)from(847,182)]what();mul(530,540)}'mul(20,999)why()::mul(801,920)/)where()how()mul(984,512)}who()<]where()mul(698,898);when()-from(552,362)>- ^how()>mul(890,685)[;$;#where()how()+mul(239,920):(@;%when()+mul(88,839)&^)@why()what()how()where()[mul(572,398)what()$mul(752,549)what()when()'>[<when()<?mul(10,251),^~from(),where())#mul(569,478)where()~select()'mul(411,622)^-'+{mul(784,824)mul(641,531)mul(315,701)[mul-^(%when()mul(824,525)#$@*:+:}>mul(732,854)(+@ {(who(621,788) mul(86,481)how()@*'mul(954,533):how()'from()}-when()mul(826$]}how()mul(482,558){%what()^/&)}^[mul(45,414)}how(){;&how()~#mul(300,115)*)?select()<]%mul(374,474){#select()#mul(215,47)who(){^++?%{&mul(332,567)$mul(357,321)/from()#( why(496,793)mul(501where()@}who()select()}mul(62,985),!select()}#+{{]mul(211,725)?]< :how()select()mul(958,722)#'where()!what()@$mul(157,358)mul(998,511)mul(97,681)*;mul(206,463))*mul(790,146select()when(199,114)&[%!';select(){who()do()mul(960,474^}+why(960,681),~>[why(701,791)mul(865,506)?-;select()/~@do()+{'what()~select()%+mul(638,544)) >$^*<where()select()(mul(501,647)@#~when(136,478)()*;^mul(48,956)how(),what();^^when()from()^mul(501,473)what()!what()mul(820,536)}mul(772,914)+-$from());+?-#mul(76,607)//mul(705,35)who()*what()!{how()mul(733,730)from()*where()+<mul(821,893)mul(947,531)select()^who(),{how()where(610,667)where()mul(889,663)where()where()#/^mul(493,430)^mul%why()-?what()mul(139,704)@select()mul(923,691)>mul(583,859){[mulhow()>who()/?^~%mul(19,182)~select()select()select()**+mul(77,374)&@??when()>[mul(630,751)mul(740,291)){@*{what()what()@&who()mul(760,727)where()<^ >][mul(996,13)}{%*when()+*mul(865,56)*]mul(995,58)how()}what()@!!)';(mul(323,37)~mul(348,89);{when()~)'mul)'>what()<$%who()%don't()from(533,539)?'~-'where()-+?mul(917,600);from(672,658)mul(966,120)/'@/'^mul(895,427)mul(842,971)',@mul>who(){mul(670,166)where();)^don't()~$+#:when()?!mul(871,536)who(67,974)do()##select()>+(#mul(502,269)!$[^where()where():where()mul(652,742)
 | 
					 | 
				
			||||||
from()#%;why()(why()?mul(43,859){(who()]-:{mul(162,15):>how()@%$:mul(322,158)what()$&*{how()mul(949,468)where()?what()+mul(890,635)@;mul(937,114&+:where()#mul(516,431)who()mul(516,755),}who()'!mul(484,114)*}who()who()]mul(623,440)!%{{why()how()}mul(774,302)&)[{select(873,278)-@mul(91,958)<}?-,>+/from()}mul(910,920)']:~how(996,958))why()@mul(134,589)<''when()mul(853,477*$!mul(204,437) where()#how()>~who()*mul(697,199)[-~}select()mul(928,999)!what()when()!>mul(721,616) }why()%)mul(166,276),^$$[when())-why()mul(921,345)&when()'how()-mul(858,22):when()mul(812,54)how()%@%^&mul(11,654)where()^!)%mul(398,677)what()what()[/$:who(279,228)#mul(649,529)mul(78,877):mul(265'&}!why()how()mul(826,788){*:{?,who():mul(463,163)select()mul(342,950)mul(339,663)from()where(){,who()<:?why()when()mul(568,433)$,select()?mul(182,776)^/*,<%*select()%mul(705,962)what();}mul(717,100)from()mul(664,69 % *mul(423,876);from() who(),mul(630,98)[:?how()from(718,704)mul(356,570)#why()select()')from()@:mul(193,467)when() !!)select(625,819)/(!when()mul(171,718)do()<:,what();select(){$}?mul)+mul(20,284)$/,~from()],^mul(984,419);; mul(503,701)+[(;select()?/mul(634-how()mul(424,769))~ -where()* }who(484,481)how()mul(707,101)*do()where())select()(from()]#who(335,623)when()who()mul(911,436)what()<mul(194,212),why()/>}mul(777,219)what()['}when():select()mul(948,616)<from()$,#mul(553,209;;)-;what()*mul(728,277)?-{select()[when()^@'@mul(587,483);^%mul(399,787)&{who()$,mul(915+what()!why()}!who(610,136)+what()mul(226,744)*@from()@):]mul(384,508)when()-how()mul(71,783)#mul(358,304)/select(114,878) [}where()why()%)?mul(45#]when()'*+when()who()mul(914,176)when()@(who()&select()&mul(326,407)mul(506,431)what()})^$}~&*{mul(906,775)from()where()(]~mul(969,415)mul(710,613)+*select()mul(312,425)():}^!{*)mul(766,549)from()<:[/%'mul(782,679)'!select()~#>%/mul(476+&!&who()'<how()who()(mul(876,214)select();&from()'mul(120,331) !~',/mul(276,127)]%]who()([-what()mul(36,647)how(144,302)&^from()%mul(166,678)who()mul(577,776))+&>>@]'mul(540,542)select()%when() mul(21,652)^#why():?,![<mul(696,919)!why()when()>where(),+#{+mul(957,516)select()@who()!mul(949,720)$ >from()[>when()@mul(302,42)*when()};mul(62,497>~~)@<mul(730,949)how()from()>how()why()*(mul(664,358),mul(739,738)?/)from()//mul(377,419)}{-what()~why()^[]mul(40,477]#+?]don't() when()]mul(870,3)why();%?-how(721,560)$);[mul(568,692)+~how()mul(638,590)~% ?]mul(901,665)+:;?mul(518{&(+~/#when(87,181)@what())mul(675,719)}why()  do() ;^mul(596,35) )mul(427,664){<mul(197,195)@/~#when()do()>when()what(){select()+%}mul(737,893) mul(709,889)!-@,when();where()mul(129,840)when()mul(920,817)#]?^?why())@@mul(269,369) mul(828,795)@*;where()mul(682,546)from(){/mul(243,207)mul(503,124)[from()where()&what()&}(mul(750,321)how()>'&)mul(970,615)why()~mul(876,7)&:%select(836,319)$who()&mulwhere())/]{mul(312,66) ~'%why()from()mul?{select()] ;?*?select()mul(453,529)why(117,235)^do()@'-+from(370,703)mul(644,160)<[,mul(227,457)~}%%select()^>select(360,884)]mul(925,534)-select()'mul(739,218) &/&how()~^mul(332,459) (&{!select(856,366)-don't()()when()-from(487,696)%?what(768,731)mul(745,482)[,select()mul(880,43)^why()mul*@[[+where()what()how()mul(546,582)from()[/&why()mul(308,97)mul(343,420)}when()~mul(824,505)why()?!who(),mul(261,37)what(580,629)^-mul(554,10)$} %)?^*+mul(519,543)!{&#*mul(71#+select()&'why()*mul(67,843)~>where()]mulwhat()where()/[what() who()(/@/#!/usr/bin/perl&>mul(708,675)
 | 
					 | 
				
			||||||
@from()[$from()why(548,875)mul(121,80)}:$-mul(4,306)mul(763,819)how()~)}'<who()why()when()mul(496,223)select()]don't() (mul(667,275)*who()?&+[do()+)&,what()#/mul(345select() what()mul(173,615)$/;select()select()~mul(942,267)[/^<!',<why()how()mul(32,848[<select()&~+mul(428,140)mul(601,739)who()how()select()}@how()@>what()do()mul(185,413)*don't()how())>:-]mul(988,832)from()#? what():how()~what()?mul(186,334)select()mul(302,939)*&{#+:)+do()[~+'mul(981,447)do())(how()where()&what()?][&mul(31,754)$?*^+-%(>)mul(851,878))>what()^#$do()]?,)mul(470,861)/!what()mul(861,914)@}when()when(535,739)/where()mul(404,36)why()where()do():}mul(192,10){,from()]!'!when();mul(439,983)when()?*where()who()mul(264,570)/where())mul(118,609>~])&<;+what()}mul(740,187)-!why(),{- <&mul(515,176)why()(#&?$who())^mul(861,78)mul(425,831)^*}don't()&);how()]mul(983,533)/mul(871,157)why() why()mul(822,445)*?>/{}what())mul(466,451)what():+?mul(362,799)select()@{~^^mul(808,226),mul(847,636)how()'select()+?mul(965,149)##?~mul(898,404)$select()! mul(704,590)~mul(453,171)!:why()#^< mul(667,115)>select()from()who()how()?/<how()mul(130,444),[how()(%+,from();mul(886,298),]-~when() >mul(689,875)why()what()})&!&mul(51,975)^]what();:when()don't()[;$ where()why()mul(71,129)who()%mul(841<@<mul(464,159)>mul(61,222)$;[#~~mul(433,310)>from()how(932,844){?-%mul(172,290)select()''how()*-where()%when()mul(868,592),(select():*:/mul(313,54)}from()how()^*]-where()+do()(--select()what(),/ mul(867,197)mul(203,803)+when()%;-where()%<-don't()]]@where()why()!#why()!mul(949,149)]?mul(960,580)how()mul(12,600));mul(210,348)*mul(565,871)'%where()mul(577,267)!#)mul(474,282)<<from(){where()&<)when(){mul(534,990)how())mul(348,523)how()+[*'select(){{mul(610,625){-mul(125,779select()!from(){)*what()mul(237,916)mul@]how(),;{@select()~do()) @;?who()~<#mul(641,477)%select()/*mul(66@/# ]#when()/,-@mul(398,141))where()*mul(17,892)mul(447,218*from()}~~%%::,<mul(581,913)what()who()/@+*who(507,341)mul(485,202)mul(637,719)@~!]]%[}mul(152,221)who()where()select()^why()<@(mul(336,492)who()>#>%when(255,810)(mul'why()+*when()how()~->]mul(76,674)what()}}%where()where(552,574)mul(172,533)why()mul(166,405)(from()#/how()how() ^^(mul(580@( ^how()from()mul(168,469)}]@how()~mul(319,476)^]from()(what()'>/,^mul(953,57)# how()select()mul(534,477):select(791,428)~$,when()mul(504,444'mul(534,163)where()# %why()!mul;,why()from()}'mul(819,924):mul(914,787) #?select():!+%];mul(743,314)[?#{mul(127,154)how()+[@!]mul(402,199)!)why(774,912)?~,( where()&mul(747,407)don't()>what()where()'why()why()why(844,133)mul(649,89)mul*when()mul(878,257)!>%#>;select()mul(371,837)-;from()where()~-mul(314,883){}mul(952,191)(-#-mul(400,750)what())what()mul(83,753) +who()!<select()[~<+do()why()?who(){;++mul(315,12)from()%where()(why()%mul(244,473);%-/}*$@do()select()['+*why()from()mul(503,91)why()&(mul(718,938)]!}when(217,970)do()]mul(695,933)^/mul(643,847)!-~%mul(599,777,*{'from()when()}from()?*do()/who()]how()) ]%{mul(128,209)/?mul(145,427):mul(838,702)who()~&^:mul(750,117),why()$when()-;%mul(105,945)!when()%how()$<%;mul(445,716)/,/+'mul(848,545) :;:(from()don't()-/)&{$mul(645,418)select()&'[+%/&mul(805,629)$mul(409,212)when()?where()(%who()why(),mul(341,178){![from()^select();from()when()mul(53,969)<;select()mul(351,259)~]%&/-why()mul(22,26)&]>select()$}mul(79,756)where()^?',-mul(273,582) why()do()&~) what()what()mul(92,844)where()!what()/>> {%mul(678,890)mul(784,836)mul(184,623)
 | 
					 | 
				
			||||||
who()mul(590,239)%%mul(67,657)when()({]mul(556,689)when()/+: :<mul(570,791)when(500,731),}<--'mul(315,20#mul(353,577)]<mul(147,848)mul(974,10)^from()how()what(){( ?mul(500,481);from()*]'{@mul(145,394)why()where()?]?what()mul(97,499)mul(784,687)^[]:how(823,116)mul(290,184)who(27,581)+[~}}@*(;mul(553,555) when()/mul(317,461)mul(789,586)what(787,924)>(who()$,~])mul(810,145)$from()^/)?(/>mul(468,772)(~(who()mul(663,347)where() #how(572,145)!<&;mul(704,336)%$++!mul(170,815)from();why()mul(944,939)]select()<mul(280,533)why()mul@[who()~:[?)from()/how(159,441)mul(738,82)~ from(858,110))%~~*~mul*mul(488,256)/>!mul(584,361)what()~why()[why()>,~<mul(896,700) ')}who() !>mul(794,457)from()~,how(898,290)don't()mul(889,959)where(594,614):who()*/-mul(786,550)!how()mul(481,863)*!select()who():@mul(980,469)when()-&*#~[*~mul(972,650);&from()$!/:$mul(140,685)]</*%:mul(884,90)select()&}why()!from()&?how()^mulwho()'?select(213,664)why()&why())@^mul(90,714)where()!why()mul(874,305);:$who()+:[mul(5,462)why()mul(102,265)>/~[{where(409,316)mul(232,721)>why()who(902,515)who()$!where()/>mul(247,605)'what()select()mul(936,163)mul(591,955)how()mul(931,542)how();what()'*;where()<mul(224,284)~/@mul(878,735)}>&<(,mul(55,798) ,[+what(){^mul(441,281)?mul(570,318)mul(973,304)}what()]mul(45,721)#?@?where()(<!#mul(38,985)mul(615,729)!^)from()  ,}!don't()^,~>>!#mul(701,624)select()[-mul*{mul(67,259)(({%+  -+mul(986,986)&from()who()-'mul(726,819):mul(490,252) what()+how()select()-why(423,93)mul(694,82)-how(328,923)>'how()&(%what()*mul(372,723)'?!!}mul(231,968)-!%mul(415,363){mul(723,230why(141,301)^when()mul(123,44)how()#-who(){&!{mul(513,206)mul(651,372)/#'who()%when()when()^how()mul(894,333)*>mul(789,454)mul(527,63)]}!][#-:mul(696,451)-mul(725,992)/({mul(951,218)/*,who()(];}$mul(999!how()+why()~what()$#)(what()mul(866,336)&when()@!]mul(277#+why()when()where()]mul(625,228)don't()how()*from() mul(728,218)[<&mul(685,966)when()]([':>mul(88,454):,mul(980,618)[:mul(983,851)from() (where()mul(136,951)mul(923,850)select()^what()when()where();{-mul(574,853)'!%select()[how()~)!~don't()>+*mul(999,45)%how()$*^mul(663,51)what() mul(72,914)when()where()^*>';from()mul(717,449)from(116,874)!#}^~$()why()mul(253,711)!-?[where()where()$<mul(413,791)why(),&where()mul(881{:why(457,236)^$mul(579,940)^!+-#[mul(365,458)*what(826,843)mul(905,802)',from()&?*,/who()#mul(706,256):#mul(397,960,/}mul(886,736)@)??mul(483,8):when())where(835,379)'where()who(206,272)mul(41,664)~-^(when()(!:how()mul(65,540)select()where()%from()'{mul(422,122) ~mul(31,555)~select()mul(368,343)<$$~>-@do()%#+&&why()&?who()mul(575,697)*{mul(124,326) )};}why()/')mul(524,584)from())who()?~mul(245,768)!how()@)mul(704,867)^from()]%$(?when()mul(90,724)-;]why()?mul(434,982)%[$from()/-mul(947,645)%what()from()~*;why();-mul(637,644)mul(728,998how(363,38)]#[mul(968,268)mul(118!}how()who()&+$mul(512,161)/~+mul-who()mul(627,181);when()&do()}#;select(139,567)what()*from()-why()mul(914,709)mul(372,426)select()/select()(:mul(573,160]select():mul(439,918)mul(8,169)&why()^'mul(417,187))([who()/when()who()>mul(715,150)-how(609,180),mul(208,512)'why()':&mul(998,345)
 | 
					 | 
				
			||||||
[:~from(109,28)mul(762,958)-mul(962,739)%mul(808,716)'{(]},<;mul(937,746)where()select(731,533)select()[,how()}select()who()mul(191,854)where()mul(479,494>*why()mul(453,745)/%/mul(857,414):>who() ?mul(724,307))(<&select()mul(514,942)why()<,where(857,995)why()who()(mul(499,812)how()why()select()@,{@,^$mul(870,75){where()%when()}mul(715,952)mul(679,508)]-*#~mul(976,825)@what(311,818);}>+don't()from()!(mul(831,784)select(401,869)>##what()}$}mul(485,631)%when()don't(){%[<mul(650,982)how()'from()%[/how()/mul(435,53)?&!{how()[::mul(131,389)^,what()/>%where()mul<mul(169,929)*mul(299,197)'(?/mul(615,378)select()>^!'@select()$when(194,342)mul(955,305)when(714,487)!~[mul(132,571)&<<[?}select(424,232)what()mul(728,300)select()where()@>{*mul(695,119)mul(350,526)~/what()when(),?'mul(166,855)%!,who()}why()from()}what()#mul(197,953)from()}from()?mul(608,965)$*]/,(when()what(),mul(393,927)@ what()how(),/mul(157,25)}%:who()-how(727,121)who()[mul(335,527)[%^,>/&where(){select(415,462)mul(450,651)@-where()when()%&('mul(741,677)#what()-:? ;+when()?mul(783,55(!' <{who()when()#(mul(905,243),mul(822,319)>select()- )#why()'^+mul(837,766)^who(69,740);{,{}^?mul(495,650when()select()when()(%why()mul(298,908)?from()-where()mul(781,697)%<mul(802,337)how()who()mul(912,22)<how()]where()-+from()mul(769,224)/}]where()mul(727,470)#^)!@,don't()+/&why()]who()(&mul(653,780))@ <how())who()/<mul(246,377)( where()~when() :where()mul(189,554)(mul(902,862)from()%^what()how()%<where()$mul(542,480)(/?,%mul(413,772)#mul(63,506)((+{ ;*^@:mul(114,204)+@>)<what()what()]mul(245,578)~select()mul(320,125)*{ [:#how()<{+mul(406,999)mul(577,430)who()%! why()*&where()?don't()$@$what()who()who();>$[mul(661,538)<{-&<select()'}mul(200,315)mul(112,246)where()where(404,923)from()%+';<^$mul(122,413)select()what()mul(721,764)/}what()why()'$)!<mul(892,451)>%%&$-how(),,what()mul(634,148)[mul(13,464)*'?what()'$%mul(311,661)]?how()don't()[>^]%when()# where()what()mul(5,587)+!-what() +mul(618,897)#where()where())how()<mul(343,790)??->{mul(944,841)@'?<mul(954,120)/*from()&what()what()/~/mul(86,632)from()?;<$:mul(607,376) select()!%mul(47,177)}/~*mul(800,210):when()what()}who()why()why()$,how()do()-/who(),where()mul(113,797);]+from()^mul(819,538)what()~why();^when()where()don't()mul(267,315)-?who()>,(~~mul(970,389)*,')mul(285,941)^#mul(554,821),&}]/when()mul(906,954)who()why(),!!()why()mul(89,545)~;) why()*)mul(507,709)@mul(977,650)+]how()-, mul(204,198){/$'~}<{]}do())? +;/why()select()%*mul(226,790)< >how())from()$ ;#mul(901,307)?when()+when()when())mul(19,239)>where()(when() mul(964,735)from()mul(484,646)select() ,;@how()$');do()^#what()mul(297,515))#*{;</mul(491,320)(;+%')mul(675,449)$}*when()!}@mul(21,16)who()(from())[/*?'mul(263,684)~{{when()from()+mul(751,630)[(?mul(445,676)~~mul(840,40))+how()-~what()mul(298,977)from()>%&~select()mul(404,614))~)[mul(182,657),{from()mul(450,272)(mul(228,343):what()[what()%(mul(970,721) #%> why()mul(879,558) %+?do()-)select()]mul(723,300); *why()mul(384,706)?)do()mul(799,503)~select(327,603)when()<>mul(216,403)select()<{(,mul(721,553)from())?when()mul(319,645)don't()*';how()where()(how(151,143)mul(675,236)<mul(242,159)*mul(532,562)mul(923,707)mul(13,834)&-where()
 | 
					 | 
				
			||||||
@ -1,228 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"iter"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// var log = aoc.Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() { aoc.MustResult(aoc.RunnerReader(run)) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type result struct {
 | 
					 | 
				
			||||||
	valuePT1 int
 | 
					 | 
				
			||||||
	valuePT2 int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func run(read io.Reader) (*result, error) {
 | 
					 | 
				
			||||||
	sum := 0
 | 
					 | 
				
			||||||
	sum2 := 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lexer, stop := Lexer(read)
 | 
					 | 
				
			||||||
	defer stop()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	active := true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for lexer.NextTok() {
 | 
					 | 
				
			||||||
		switch lexer.token {
 | 
					 | 
				
			||||||
		case "TokMUL":
 | 
					 | 
				
			||||||
			if m := readMul(lexer); m != 0 {
 | 
					 | 
				
			||||||
				sum += m
 | 
					 | 
				
			||||||
				if active {
 | 
					 | 
				
			||||||
					sum2 += m
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case "TokDONT":
 | 
					 | 
				
			||||||
			if readDont(lexer) {
 | 
					 | 
				
			||||||
				active = false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case "TokDO":
 | 
					 | 
				
			||||||
			if readDo(lexer) {
 | 
					 | 
				
			||||||
				active = true
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &result{sum, sum2}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func Lexer(in io.Reader) (*lexer, func()) {
 | 
					 | 
				
			||||||
	seq := func(yield func(rune) bool) {
 | 
					 | 
				
			||||||
		buf := make([]byte, 256)
 | 
					 | 
				
			||||||
		s, _ := in.Read(buf)
 | 
					 | 
				
			||||||
		buf = buf[:s]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for len(buf) > 0 {
 | 
					 | 
				
			||||||
			for _, r := range string(buf) {
 | 
					 | 
				
			||||||
				if !yield(r) {
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			s, _ := in.Read(buf)
 | 
					 | 
				
			||||||
			buf = buf[:s]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for !yield(-1) {
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	next, stop := iter.Pull(seq)
 | 
					 | 
				
			||||||
	lex := lexer{iter: next}
 | 
					 | 
				
			||||||
	lex.readRune()
 | 
					 | 
				
			||||||
	lex.readRune()
 | 
					 | 
				
			||||||
	return &lex, stop
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type lexer struct {
 | 
					 | 
				
			||||||
	rune rune
 | 
					 | 
				
			||||||
	next rune
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	iter func() (rune, bool)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf     []rune
 | 
					 | 
				
			||||||
	token   string
 | 
					 | 
				
			||||||
	literal []rune
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) readRune() {
 | 
					 | 
				
			||||||
	if l.rune == -1 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if r, ok := l.iter(); ok {
 | 
					 | 
				
			||||||
		l.rune, l.next = l.next, r
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		l.rune, l.next = l.next, -1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) loadRune(tok string) {
 | 
					 | 
				
			||||||
	l.token = tok
 | 
					 | 
				
			||||||
	l.literal = append(l.literal, l.rune)
 | 
					 | 
				
			||||||
	l.readRune()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) loadNumber() {
 | 
					 | 
				
			||||||
	l.token = "TokNUMBER"
 | 
					 | 
				
			||||||
	for strings.ContainsRune("0123456789", l.rune) {
 | 
					 | 
				
			||||||
		l.literal = append(l.literal, l.rune)
 | 
					 | 
				
			||||||
		l.readRune()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) loadString(accept string) {
 | 
					 | 
				
			||||||
	l.token = "TokSTRING"
 | 
					 | 
				
			||||||
	for !(!strings.ContainsRune(accept, l.rune) || l.rune == 0 || l.rune == -1) {
 | 
					 | 
				
			||||||
		l.literal = append(l.literal, l.rune)
 | 
					 | 
				
			||||||
		l.readRune()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) NextTok() bool {
 | 
					 | 
				
			||||||
	l.literal = l.literal[:0]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch l.rune {
 | 
					 | 
				
			||||||
	case 'm':
 | 
					 | 
				
			||||||
		l.loadString("mul")
 | 
					 | 
				
			||||||
		l.token = "TokMUL"
 | 
					 | 
				
			||||||
		if string(l.literal) != "mul" {
 | 
					 | 
				
			||||||
			l.token = "TokILLEGAL"
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	case 'd':
 | 
					 | 
				
			||||||
		l.loadString("don't")
 | 
					 | 
				
			||||||
		switch string(l.literal) {
 | 
					 | 
				
			||||||
		case "don't":
 | 
					 | 
				
			||||||
			l.token = "TokDONT"
 | 
					 | 
				
			||||||
		case "do":
 | 
					 | 
				
			||||||
			l.token = "TokDO"
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			l.token = "TokILLEGAL"
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case '(':
 | 
					 | 
				
			||||||
		l.loadRune("TokLPAREN")
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	case ')':
 | 
					 | 
				
			||||||
		l.loadRune("TokRPAREN")
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	case ',':
 | 
					 | 
				
			||||||
		l.loadRune("TokCOMMA")
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case -1:
 | 
					 | 
				
			||||||
		l.loadRune("TokEOF")
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		if '0' <= l.rune && l.rune <= '9' {
 | 
					 | 
				
			||||||
			l.loadNumber()
 | 
					 | 
				
			||||||
			return true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	l.loadRune("TokILLEGAL")
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func readMul(lex *lexer) int {
 | 
					 | 
				
			||||||
	if lex.token != "TokMUL" || string(lex.literal) != "mul" {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var a, b = -1, -1
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokLPAREN" {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokNUMBER" {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	a = aoc.Atoi(string(lex.literal))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokCOMMA" {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokNUMBER" {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	b = aoc.Atoi(string(lex.literal))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokRPAREN" {
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return a * b
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func readDont(lex *lexer) bool {
 | 
					 | 
				
			||||||
	if lex.token != "TokDONT" || string(lex.literal) != "don't" {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokLPAREN" {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokRPAREN" {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func readDo(lex *lexer) bool {
 | 
					 | 
				
			||||||
	if lex.token != "TokDO" || string(lex.literal) != "do" {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokLPAREN" {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !lex.NextTok() || lex.token != "TokRPAREN" {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/matryer/is"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed example.txt
 | 
					 | 
				
			||||||
var example []byte
 | 
					 | 
				
			||||||
//go:embed example2.txt
 | 
					 | 
				
			||||||
var example2 []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed input.txt
 | 
					 | 
				
			||||||
var input []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestExample(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(bytes.NewReader(example))
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 161)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err = run(bytes.NewReader(example2))
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 161)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 48)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestSolution(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(bytes.NewReader(input))
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.True(result.valuePT1 < 186942148) // first attempt too high
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 184122457)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 107862689)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
MMMSXXMASM
 | 
					 | 
				
			||||||
MSAMXMSMSA
 | 
					 | 
				
			||||||
AMXSXMAAMM
 | 
					 | 
				
			||||||
MSAMASMSMX
 | 
					 | 
				
			||||||
XMASAMXAMM
 | 
					 | 
				
			||||||
XXAMMXXAMA
 | 
					 | 
				
			||||||
SMSMSASXSS
 | 
					 | 
				
			||||||
SAXAMASAAA
 | 
					 | 
				
			||||||
MAMMMXMMMM
 | 
					 | 
				
			||||||
MXMXAXMASX
 | 
					 | 
				
			||||||
@ -1,140 +0,0 @@
 | 
				
			|||||||
XMXXMSSSMSXSXMMXSAMMXXSXMASMSSXXMAMXAMXSXMXSMAMMASXXASMMXMASXMSSXMMMXMXSXXSXMXXSAMXSXSXSAMXMSAMXMAXXXMXMAMSASXMSSXMSXSXXMAXXSSSMXMXMXMMAASXM
 | 
					 | 
				
			||||||
MSSMMAAXAMMSAAAXXAMSXMAMXMSMAMMXSAXMXMASAMASMAMMASXMAMAXXXMASAAAXMSMSMAMAMMAMAMMMMXMASMMXMXAMASXMAMMMMASMMSMMMMASAAXAAMMMMSMXAAMSAMSASMMMMAX
 | 
					 | 
				
			||||||
AAAXMMXMSMASXMMSMXMMASMAAMXMASAMMAXSAMASAMASXXSMASASMSMMMMASMMMMMMAAXMXSAMSAMASMASAMAMASMMMMSAMXMAXAASASAAXAAXMASMMMSMXAAXAAMSMMMAXMAXMAASMM
 | 
					 | 
				
			||||||
SSMMXSAAXMMSAXMAXAAXAMXXMSSSMSMAMAMXAMXXXMXSXMMMMSAMXAXXAMXAXXMAXMASMXASAXXMSAXXASAMAXAMXXAXMXXMSASXMMASMMSSMSMMSASAMXSSSSMSAAAXMMMMXMMSXSXA
 | 
					 | 
				
			||||||
XAAAAMMSMSXXMXAASXSMSMSMXXMAMXMASXSSMMXMAMAMMMAAMMAMMMXSSMSAMXSMSASMXXMSXMAAMAMMMSXMAMMSXSASASAMXASXAMAXMAAAAXXMSXMXMXMXMAXAMXSAXAAXAXAXAMXS
 | 
					 | 
				
			||||||
SXMMSXAXASXAMMMMSXMXMASXMMXMMSMAXXMAMAMXAMASASMSMXAMXMMAMASAMXSXMMXAXSXSAMXMMAMAAMXMASMAXAAMAMSMMXMMMMMSMMMSAMXAXMMMSXSASMMMSMMMSSSMMMMMAMSM
 | 
					 | 
				
			||||||
AAXAXMSMAMSMMAAMSMSAMMMAMAASASMASMSAMAMMASASASXMASMSMSAAMAMAMAMASXMMMAASXMAXSASMMXAXAMMMMMSMXMAXSASASAMXXSMMMSMMMAXAAASAXSAXXAAAMAMXSASMXMAS
 | 
					 | 
				
			||||||
SSMMSMAMSMSXMSMMSASXSXSAMSMMASASMMSASASMXMMXMMXMASAAAXAMMXSAMASMMMAXXMMMXSAMXXSAMSMMSSXXAAAMMSSMSASXMASMXMASAXAMSSMMMMMMMMXSSSMXSAMXSASXMSMS
 | 
					 | 
				
			||||||
XMAMAXMXXAMAMAMAMXMXXASAXAXMXMXASASAMASMSAMXXSSMMMMMMMAMXMSASXMMASMMSSMMMSMMMMMMMASMXAMSMSMSAMXAMAMAXAMMMMAMMMSAAXSASASASXMAMAAXMASXMMMMXSXS
 | 
					 | 
				
			||||||
SMASXSXASASAMAMXSSSSMASXMASMSMSAMXMAMXMASAMSXMAASAMSXXMMXASAMXMSAMAAXXAAAMAMMAAMXAXXMAXMAAXMAXMXMSMSMMMMAXMMSAAMXSMXSASAAMAMSXMMSXXAXAAXMSAS
 | 
					 | 
				
			||||||
XMAXMXAXSAMXXXMAMXAAXMMMXAAAAAXASMSSMXMXMAMXASAMMASMXSXMXMMAMAAMASMMSMSMXSAMXMMSMSSXSXMMSMSSSMXXAMAXMAXSAXMAMXSAMXXXMMMMMASXSMSXXMMMSMMMAMMM
 | 
					 | 
				
			||||||
SMSSSXSAMXMMSMSMXMSMMAAXXSXSMMSAMAMAXXXXSAMSAMASMXMMASAMXXMAMSSSMMAXAXAXXMMXSAMSAMAMXAXXMXAAXXAXMMSMMSAMXSMASAMAASAMSAMXXSMAXAMMXAAMAMXSMSMS
 | 
					 | 
				
			||||||
SAXAMAXAMAAASAAAAMAXMMXMMXMXAMXAMAMMMMMMSSXMAXAMAXAMMMMSAMSMXXMAMXMSXSMSMSAAXAMMAMMMSXMMXMMSMAMSMAMAAXMSAAXAMXSMMAMAAASXMMMMMSMMMSXSASMSAAAA
 | 
					 | 
				
			||||||
MMMAMMMSXSSMMSMSXSAMMSMMASXMSMSMSASXAXAXMXXSXMSSXSMXSXXXAXAMMMXAMAAXMSXAMMMSSMMSAMAMAAMSAMXAMAMXMAXMMSAMXSMMSAXASXXXSXMXXAAAAMAMAMXSAMAMSMMM
 | 
					 | 
				
			||||||
SSSSMMXMXMXAAMXMASAMSAMMAXXAAAAAXASXMSXSAMXMAXXAXXMASMSMMSMSAMMSSMMXAMSXSAMXAMAXXXASXMMAMMXXSXMAXMXSAMXMAMMXMASMMMSXMAMAXXSSMSAMSXMMSMMMMMMM
 | 
					 | 
				
			||||||
SAAXMMAMAXSSMSAXAMAMMAXMMSMSMMMSMSMMXAMMXAASMMMXMAMASAAAAAASMSAXAAAMMMMMSASMMMMSSMMXAXSMMSAMSAMAMSAMAMAXSXMAMAAXAAAMSXMASXAAMMMMAAMAMXXXAAAA
 | 
					 | 
				
			||||||
XMSMSMASMMMMASMMSSSMSSMSAAXXASAMXMAMMASMMSXSXAMXSXMAMXMSSXXMAMXSMMXSAAAASXMASXSAMMSSSMXAAMAMSAMSSMASXMSAMXSSSSSMXSAMXXSASMMMMAAMSSMAXASMSSSS
 | 
					 | 
				
			||||||
MXMAASMMMAASXMXXAAXMAAAMSSMSXMASAMAMSSMAAXAMMMXXMXMAXAXMAMXMXMXXXMASXSMXMMXAMXMASAXMMAMMMSMMMAMXAXAMMMMAMAMAAXXAMMMXXMMXMXSXSSMMAMMSMXMAMAMM
 | 
					 | 
				
			||||||
XAMMMSXAXSXSMMXMMMMMSMMMAMASXMAXXXXMXAMMXXASAXXAXMSAMSSMSAMXAMXMMMXSAMXAASMSSXSAMMSAXSMSAAAASAMXSMXXAXXXMAMMMMSXMAAMMMXAAXXAMXXMASAAMXMAMAMX
 | 
					 | 
				
			||||||
SASMAMMMMMASAMXMMXSAAXXMXMXMASXSMSMMSAMSSSSMAASMXMASMAAAMASMAMAAXMAMXSSMMMAXAAMXMXMMMXAMSSSMSAMXAAMSSSMMSXSXAXMAMXMMAXXMSMMMMAXSAAXASXSMMAXX
 | 
					 | 
				
			||||||
MASMMMAXAXAXXMXSXXMAMSAMMSXSAMAAAAAAXAMAAMMMXMAAAXAAXAAMMAMMAXASMXXMSMASMMMMMMMAXAASAMXMAMAXMXSMMXMAAAAAAASMMMMAMMSSXMXMAMAAXSMMXXXSAMXASMMS
 | 
					 | 
				
			||||||
AASAMMSXMAMSSMASMMMAXMASAAXMASMMSMMMMSMMSMSSSXMSMMMSAMMSXASXMSMXMAAMASAMXAXSMXSMMSXXMXSAMXXMSSMMXMMMSMMMMAMAMASXMAXMASMSMSSSXMAMAMSAXSAMXSAA
 | 
					 | 
				
			||||||
MASAMAXXXMAAAMAXAMXXXSAMMMMMMMXXXXXSAXAXMAAAMXMAXXXMAMAMMAMXAAAAMSSMAMMXMMMMAAXMAMMMMAMAXXMASXAXMXAAXMAMXASAXMAAASMMMMMAXAXXMXAMASAAMXXXAMMM
 | 
					 | 
				
			||||||
SASAMASASAMSSMASXMMSAMMMMASXMASMXMMMASAMXMMSMXSAXSMSAMASMMSMSMMMMAAMAMXSAMSSMMSMASAAMAMAMXASMMMMMSMMSASAMASASMMSMXAAAMMMMXMSMSSMXSMAAMMMXSAX
 | 
					 | 
				
			||||||
AAXAMXSAMMAAAMASAAAMXXXASASAMMAMAMAMMMMMMSMMMMMMSMASXSASAAAAAXAMMSSMSAAMAMAAXXXMAXMMSXSAMXSAXSAAXAAXMAXAAMMMMAAMASMMMSXXXAAXMAAXXMXMXAAMAMMS
 | 
					 | 
				
			||||||
MXSSSMMMMXMSXMASMMMSMMSXSASXMMMSXSXXXAXAAAAAMAAXAMMMAMAMMMMMMMMSAMMAMMXXMMSSMMAMSSMXAMMXSMMSXMASMMSMMAMXXSASXMMMAMMXAAMSMMXXMSSMXMASMMMSXSAS
 | 
					 | 
				
			||||||
XMMAAASAMXXAMMXXAMAXAAMXMAMAASXMAXMASMSMMXSMSXSXSSMMXMSMMSXXAAXMAXMXMMMSMAAAASMXAAMMAMSASXMXMSAMXAXXMSMMASAMXMAXSMSXMSAMXSAMMAAAASASMMMAAMAS
 | 
					 | 
				
			||||||
MMMMMSXMSASMSXSSSMAMSXSAMAMMMSAMXMXASAAMMMMASAMXMAMMMAXAAAMSSSSSMMAAAASAMXSSXMMXSMMSAMMMSASAMXMMMSMMMXAXAMXMSSXSAAXAMXXSAMASMSSSMXAMAASMMMAM
 | 
					 | 
				
			||||||
MASAMXMXSAMXAAXAMMXXMASASXSSSSMMMXMXSXXSAAMAMAMMAMASMMXMAMXAMXMASMXXSMSASMMMMASAMAXMAMAXXMMASMMAAAAAASAMXSAXAAMSMMSXMAXMASAMAXAAAMSMSMSAAMAS
 | 
					 | 
				
			||||||
SASMSAAAMASMMMMAMXMASAMXMAAXASXASAAMMXASMSMAMXMAMSAXSMAMXSMMMSMMMMAXXXSAMAAAXXMASMMMASMSSXSAMASMSSSMXMAMAXXSMXMXXASMMMXSAMXMMMMMXMMAXASMMSAS
 | 
					 | 
				
			||||||
MASXSMSXMSMMAXMXMASMMMSSMMMMMMMMSMXAAXMSXAMSMSXXAMXXMMMSMMASAMMXSMMMSAXMASXSSMMXXMASXAMXAMMMSXMMMAXMASMMSSMMXMXXMXXAXAAMASXAMAXMXMMSMMMXAMAS
 | 
					 | 
				
			||||||
MSMAMAMMXXASMSMXSMMXASAMXMXXAASXMMSMMMXMXMXMAMMSMMSMSAMAMMAMASXAXAAAMMMSXMAMMXSXMXMMXSASAMAXMAMSMMMSAMAAAAAMXSMMSASMMMMSMMMMSMSMXSAMXAXMMMAS
 | 
					 | 
				
			||||||
SAMXMXMMAMAMXXMAMAASMMMMSXMSSSSXAASAMSXMXXAMAMAAXMMASXXXSMXXAMMSSSMSSXXMASMXAASMXAAAMXMSASXXSAMXAAAMAMMMMSSMMMASXMAAXAAAXMAXAMAMXMASMMSSSMSS
 | 
					 | 
				
			||||||
AMMASXAMMSMSMSMSSSMXMASAMMMAMAMMMMSAAMAMSMMSSMSMSAMXMSMAMXSMXMMAXXMAMAMXMMXMMXSASMSSXSXSAMAASAMXSMSSMSSSMXXMAXSMAXSMMMSSSSSSSSSSXSAMAXAAAMAS
 | 
					 | 
				
			||||||
MXMAXMAXXAASAMAAAMMMSAMASAMASASXMASMMXAMXAXAXAMXMMMAAAMAMAXAAMMMSMMMSSXXAXAAMMMMMAAAASAMSMMMSASAAXXAAAXAXSSSSSMSSMXXAMMAMXAXXAMAASMSSMMSMMAS
 | 
					 | 
				
			||||||
XSMAXMSSMSMMAMMXSMAMMXXXSAMASXSXMXXASMXMMMMMXSSMAAXASMSSMMSSMSAMXXSMAMXMASMXSASXMMMMMMAMAXXXXAMMSMXMMMSMXMAAMXAAMAASXSMMMMMMMMMMMMAAXAXMAMMM
 | 
					 | 
				
			||||||
AMMAMSAAXMASXMXAMMASMMSMMMSXMAXAXAXAMMMSSMAXSMAMSMSAMXXMAXAAXSASMAMMAMASXSAASXSAXXXXSSSMMSSSMMMXMAMXMXAXMMMMMMMMXSXSASAMASAAXAAAAXMASMMMSSSM
 | 
					 | 
				
			||||||
AMAXMMASMXXMASAXMASAAASXAAMASMSXMMMMSXAAASMXXMXMAMMAMMSSMMSSMSAMMSMSXSMSAMMMSSSXMASXXAMXXAAAAASMXAAAMMXSAAAAAXAXXMSMASXMASMSMASXSSMMXAXXAAAS
 | 
					 | 
				
			||||||
SSMSMMMMMXSSXMASMMMSMMMMXMSAMXMAAXAAAMMSMMMXXSMMXMSAMXAASAMXMMSMXXAAAXAMAMAMMASXMMXMXMMMMMSMSMSASMSXSAXMMSSSSSMSAXXMAMAMXMXXAMXXAAXAXMMMMSMM
 | 
					 | 
				
			||||||
XAASASAAXSAMXMASAAXAXMASAXMXSASXMMMSSSXMASMSMAASAAXMASMAMSMXXAAXAMXMMMSMASASMAMMMAXSMXAXAAMMMXMAMAXAXMMXXMAXAAASMMSMXSMMASMMSMSMSMMMMSASAMXS
 | 
					 | 
				
			||||||
MMMSAMMSSMMMXMASMMXMMSAMXMASMAXXAXXAAMXSMAAAMXMMAXXXMMXSSMSMMSSMMAAXMAASASAMMAXAMSSMASASMMSASMMAMXMMMSAMSMSMSMMMMSMXAMAMASMAAXAMMXAAAAAMXSAS
 | 
					 | 
				
			||||||
SMXMAMAMXXXMAMASAMXSAMMSSMMMMAMMSMMXMAMMSMSXSMSSMMSSSMAXAAAXAAAMSSXSASMMMMMSSSSSSMAMXMAAXAXXXAXXXAASAMASXAXAXAAAMASMXSAMMSMSMSMAXASMSSMSXMAS
 | 
					 | 
				
			||||||
SAXSAMXSASMSASASAMXMASAAXAAXMAMAAXMAMSMAXXXAMXAASXXAMMSSMSMSSMSMMAAAMXXAMSMMAAXMAMAMXMXMMMSSSSMSSSXMASXMMSMSMSXMSAMMXSXSXXAAAMXMSMXAMMMXAMAM
 | 
					 | 
				
			||||||
MXMMMAAMASASASMSAMSMSSMMSSMSMAMSSMMMXMMSMMMMAMSSMXMXMAXXAXXAASAAMMMMXMMXXAAMMMMMAMXSSMAXAXMAAAXAAXXSMMMMAXAXAAXXMXSMMMMMMMSMSMAMMXMSMSXSXMAS
 | 
					 | 
				
			||||||
MAMXSMMMAMMMAMASXMAXAXMXMAMAMAXMAMXAMMAMAXASAAMAMMMSMMSMXMMXMMSXMXXMXMASXSMMXSAMXXSAXSASXSSMMMMMSMMXASAMXMMMMMSXAMXMAAAMAMXMMMXSMAXXAMXMAMAX
 | 
					 | 
				
			||||||
SMSAXAASMSSMMMAMASMMMSSSSSMSSMSMASXSXMAMMSMSAXSAMAAAAMXXSXAMSAMXMASXSMMSAMAMAMAXASAMXMMXAXAAMXMXMAMSXMAXXAXASMMMSMAMSXMSSSMMAMXMMMSMAMASXMSS
 | 
					 | 
				
			||||||
XAMMSSMSAAMXXMSSMXXXXAAMAXAAAXAMMMMXAMASAMXXMAXAMMXXSMASXMXSAASAMAMMAAMMXMSMMSSMMSSXMSSSMSSMMMSMSAMMXSAMSMMMXAAAASMXMXMMXAMMMMAMAMXMAMMSAAXA
 | 
					 | 
				
			||||||
MMMMAMMMMMSSSXAAXXMMMMSMAMMMMXXMAAAXXMAMMSSMMSSSMSXMMMMMAAXXXMMAMASXSXMAXXXAXAMAXXASAMXAXAAAMAAXSMSAAMAMAASMSSMSXMXAMASXSXMASMMSXSASASXSMMMM
 | 
					 | 
				
			||||||
XXAMSSMXAXAASMSSMMMAAAAMMMXXXMSXSMXSAMXSMAXAXMAXAAMSASXSSMSMSSSXMXSXMAMMSMSMMXSXMAMMXXXMMSSMMMXXXAMMMSXSMSMAAMMXXMSXSAXAMASASAXAAXASAXMXSAAX
 | 
					 | 
				
			||||||
SSMSAAMSSMMMMMAAXAXSXXSSSMSSMMSAAAASAMASMSMMMMAMMMXSASAAMAAASAMXMASMSAMSAAAASMMMSAXSSSSSMXMAASXSMMMSXMXMMMMMMXXAMMMAMMMSMAMASMMMSMXMXMMAMXMS
 | 
					 | 
				
			||||||
AAXXMMMAMXAMXMXMMSMXAAMAMAMXAAMSMMMXAMASMAASAMXSASAMMMMMMXASMXSASMXAXASMMMMXMAAAXAXXAAAMMAMXMAAXAXASAMMMASXSMMMMSAMXMXAMMXSXSXMAXAMXXXMASAXM
 | 
					 | 
				
			||||||
SSMSXXMAXSAMXMXXAXAMMMSAMXMMMMXMXXASXMASMSMXASASASMMAMAXMMMMMMSASXSSMXSMAAMASMMSSSMMMMMMSSSSSMMSSMASAMAMAMXAAAAXMMSMMMMSAMXMMMMAXXMXMMSAMASX
 | 
					 | 
				
			||||||
MAAXMXMMMMSMXAAMXMMXMASAMASXASAMXXMAXSXSAXMSMMXSAMXSASMSMSAAAAMAMAXAAXMMSSMASAAAAAMSMXSAAXXAXXXXMMMMAMSMASXSSMMSXAAAXAXMAXSAASMSSSMASXMXMSAX
 | 
					 | 
				
			||||||
SMXMAAXSAXAXXMXXXAXSMMMAXAMMAMXSXSXMXSAMAAASAMAMAMASMSAAASMXSSMSMSMMXSAAAAMSMMSMSSMXSAMMMSMMMSAMXAMMSMXMASAMXXMAMSSSSSMSAMXSXSAAAASXMAXAXAAX
 | 
					 | 
				
			||||||
SAASXSXSXSMSMMASMMMASASMMSMSSSMMMSAMXMAMSAMXAMXSAMXSXXAMMMXMAMXAAASXASMMSSMXAXXAAMXMMMXAAAAAAXMASASAAXAMXSAMAMMMMAMXXXXMASAMMMMMSMMMSSMMXMSM
 | 
					 | 
				
			||||||
MSMSAXXMMXXAXAAMAAAAMMSMAXAAAAXMASXMASAMMSXSXMAMXSXMXXXXSAMMASXMSMSMMSAAXAASXMMMMSAMASMMXSMMMMAMSAMXSSXSASAMXMAMMAMMMMXXAMAXAXAAAAAXAMXSAAXM
 | 
					 | 
				
			||||||
MAXMMMXSASXMSMSMSAMXSASMXMMMSMMMMSASXSXSAXXMASXMAMAMMMMMMASMASAXAAXXMMMMSAMXMXAMASXXAXAXAXMAMXSAMMXSAMAAAXXMAMASMMMAASAMSSMMSMMMSSMSSMASMSMS
 | 
					 | 
				
			||||||
MSMAMAAMXMAAAAAMXSXXMASMMMAMXMASMSAMAMAMMSMSMSAMXXAMAAAAMXMMASMMMSMSSXMXSXSAMMSSXMMASXMMXMASMMXAMAMMAMMMSSSSSMMMAASMSMMMAAAAXASAMXAAXMAXXXAX
 | 
					 | 
				
			||||||
MAMAMMSXMXMMMMMSAMXMMXMAXXAMXAMXMMXMAMAMXAAAASAMASXSSSSSSXXMASAXXXXAAXSASMSASAAMMXAXXAXXAMAMMAMAMAMMAMXXAAAXAASMSMMXXAAMMSMAXAMXXMMMMMXMAMSM
 | 
					 | 
				
			||||||
SASASXAMSSSMXAAMAXXAMXSAMMXSASXSXAXMASXSMMMMMMAMMSAAAMAAMAXMXMAMXXMMMMMASAMAMMSMASMMSSMSMSAXMASXSXSMSMMAMMMMMMMAMSMMSSMSXMASMMMSSSMSAASMSMAS
 | 
					 | 
				
			||||||
SASASMASAAAMSMSMSSSSMAMASXMAXMAXMMXSASAMASAXAXXMXSMMMMMMMMXSSMSSXSAXXSMAMMMSMMMAXAAXAAAAAMMSMMSAXAAXMAMXMMSSSXMXMAXAAXAXASAXAMAAMAASMSMAAAAS
 | 
					 | 
				
			||||||
MAMXMAMMMSMMMAXMAAAXMAXAMXXMSMSMSAAMAMAMAMASXSAMAMSXXSMMXSAMAAXAASMMAXMMSMMMASXSSSSMSSSMSMAAXSMXMMMASAMXMMAAAXSXSSMSSMMSAMASAMMSSMXMXAMAMMXS
 | 
					 | 
				
			||||||
MXMMMSXXAAAXMAMMMMMMSMSMSMMXSAAAMMSMSSMMSSXAMSAMSSSXMMASAMXSMMMMMMMMXXAXMAMSAMXMAAMMMAAXXMMSXSASXSXAXAMAXMMXMMXAAAAXXAMMXMASAMSAMXAMXMSMXSAM
 | 
					 | 
				
			||||||
SAMXAXMMSSSSMSSSMASXAMAAXAMAMXMSMXXXMAXAMXMMXMAMMXMXMSAMMSMMMXAXXMASMXMSSSMMAMXMMMMMMSMMXSMMAMAMASMXSASASMSSXSXSMMXMASXAXMXSXMMMSSXSAAAAAMAS
 | 
					 | 
				
			||||||
SASMMMAAXAAAAAAASASXMSAXMSMMSMMMXMSXSAMMSAAXMMSMMASAXMAMAAAAMSASMSASAMXAAAMXAMXXAXXAAMASASAMAMXMAMAASAMMSAAXAXAXAXSSSMMMSMAMAMAXAAASMSMXXMAM
 | 
					 | 
				
			||||||
SAMASMSMMMSMMMSMMXSAMAMAAXXAMAAXAMAAMAMMSASAXAMASASASMSMSXSMXAMXMMXSXAMMSMMMSMSMSSSMSMMMMMASXMAMXMXMMXMAXMMMMMXMXAMMAAXXAMAXAMXMMAMXMXMASMMS
 | 
					 | 
				
			||||||
MAMSMMAAAXMAMXAMXAMAMASXSSMMSSMSSMMSMSAAMXMMMXMAMASAXAXAXAMMSSMAXSAMXMAMXXSXMASAMAAXMASASXXMMSAMAMAXASMSMXXASMMAXMSSSMMSXSMSSSXXSASAMXMAMAMX
 | 
					 | 
				
			||||||
SSMMASMMMMASXMAMMAMAMXMMAAAAAAAAMMXXAMMXSAMAXMASMMMXSMMAMXMAXASXSMASXMSMMMAAMAMXMSMMSASASMAMXSASMSASMSAAMXSXXMASXMAXAMXAXMXAAAAMMAXMXAMAMSMM
 | 
					 | 
				
			||||||
XMAMAMXAAXMAASMMMSSMSSSMSMMMMSMMXXXMAMXASASMSMAXAXAASXSXSMMMMXMMXMAMMAAAASMMMXMXMAMXXXMAMMAMAMXMXAMSAMMMSASAASMMAMMSSMMMSSMMSMXMMAMMSMSMXXAS
 | 
					 | 
				
			||||||
ASXMSSSMMXMSMMMAAAAMAAXAAMASXXAXXMXSSMMMSAMXXMMSMMMXSASAMAAXMMXXMASAMSMSMSAMSASXSASXXXAASMMSXSXXXSSMMMXXMAXAXMAMMMXAAAAAAAAAXAXXMAMXAXXMASXM
 | 
					 | 
				
			||||||
XSXAXAMXSXMMSAXMMSSMMSMSMSASASXMASAXAXMMMMMMAMXAMXMAMXMAMMMXSAXAASXSMMXMAMXMSAAASAMMMSSXSAMXXMMXAXMAXAXSMSMASMXMSSMSSMMSSSMMSXMXMASXMMSMASAM
 | 
					 | 
				
			||||||
XMMMMAMAMAMASMMSMMAXAXAMXMAXMAMXXMMSMMMAMXAAAXMSSSMXMASAMXAXXSXMXAAAXSAMXMSASAMXMAAMMAMMSAMXAAMMMMSMMASXAMXAMMMMAAXMAMAAAAAASAMXMASAAAMMASAM
 | 
					 | 
				
			||||||
MMAMSAMAXAMXSMAMAMAMMSXMXSMSXMSMAAAAXASASMMSMSAAAXSAMXMMXMASMMMSMMMMXMXXAXMAMMXXMSSMAASASMMSMSXAAMASASMMSMMMSAAMSSMMSMMMSMMASMMMMXSAMMSMAMXM
 | 
					 | 
				
			||||||
XSAMSXSSSXMXXMAMAMXSXSAXAXAMXMAMSMSSMMAMXMXAAXMMMMSMSAAXAMXXAAAAAXXXASMSMSMSMSMSMAAMSMMMXAMXAMMSXSAMSAXAAMAMMMMMMAAAXASXXXMAXMASXMMMSXXMSSSM
 | 
					 | 
				
			||||||
MSXMMAMMAMSMSMMSSMXMASAMMMXXASAMMAAXXAXMAMSMSMXXSASMSAMMASAMSMSSSMXMAXXAXXXAAXAAMXMXXXXXXMMMXMAXXMAMXMMSSSSSSMSASXMMXMMAMXMXMMAMMAAAMXAXAAXA
 | 
					 | 
				
			||||||
AXMAMAMXAAAXMAMAXSXMAMXXXAMSXSXSMMMSMMASAMAAXAXXMASAMASXMMMMMAXAMMMSSMXSMSXMSMSMSMXMXMMSMSASAMXMMMMMXXAAXXXAAAMXMMSSSXMXMAXASMMSSSMSMSAMMSMM
 | 
					 | 
				
			||||||
AAAAXAMMXSXSSSMASXSMASAAMAXMASAMXAAMMAAXMSMSMMSASMMAMAMAXAXAMMMMXSAAAMAMMSAXMAMXAAASMMMAASAMXMXMAMMMSMMSSSMMMMSMMXXMAASXMXSXMASMMXAXMXAXMMMM
 | 
					 | 
				
			||||||
SMSSSMMSAMAMAXMSMAXMMMMXSMSXMXSXSMSMSMSSMXAAAASASMSXMASMSXSXSXXXAMMSMMMSASMMMAMSMSASAAMMXMXMASAMSXAAAAMXAXAXMXAAMSMMSMMAXMAXSMMAAXMMMSMMSAMX
 | 
					 | 
				
			||||||
XMMAAAAMAMSMSMXAMXMMSMMAAAXAMSMXSAXAAXMAMSXMSMMXMAAXXAXXMXSAMMMMMSAMXSXMMMMASAXXXMASMMXSAMMSASASAXMXSSMXMSMMXSMSMAAXAAXMMSAXXSSSMMSAXAMMXASA
 | 
					 | 
				
			||||||
XAMSMMMSSMXAAASMMMAXAAMSSMXSMAMAMAMXMXMAMXMXXXAXMAMAMXSAAAMAMAXAAMASAMAMAMSASMSMXMMMXXMMASAMXSXMMXSAMXXAXAASAMXAXXMSASMSAMXSAAMAAAMXMMXXMASX
 | 
					 | 
				
			||||||
SMMMAMAAMAMXXXMXXASXMSMAAMAMSMSSMAMSMSMASXAXSMSMSAXMAXSAMXSSMSSSSSXMMMAMMMMXSAAXAXMAMMSSXMMSAMAMXAMASAMMSSMMASXXMMAMAMAXMMXMAMSXMMSSMSAMSAMX
 | 
					 | 
				
			||||||
SXMSAMMSXXMSMMMSXMXAAMMXXMAMAXMAAAXAAXSAMMSMMAAASXSASXXAAAMAAAXXAXAXXXAMXASAMXMSXSMMSAAAXXMMASASMMXXMASAAAASAMMAMSASAMMMSSMSSXMXMXXXAAAMMASM
 | 
					 | 
				
			||||||
MAASXSSXXMMAXAAAAXXMSXAMSMMSAXSMMMXMXMMMXAAASXMXMMMMMXSAMXSMMMSMMMSMSSSSSXMMSAMXXXMAMMSMMSMSMSASXSXMMAMMSMMMAMXAXSAMXMSAMXAXMASXMMMSAMXMSSMM
 | 
					 | 
				
			||||||
SSMXMMAMXSSMSMSSMMXXAMAMMAXAMXSAAXASMSASXSSXMMSXXAAAAXXXSASMAASAAAAMXAAXMAMASMMMSSMSSMAMXXAAAMXMASMXMASXAXMMAMSMXMSMMXMSSMMMXXMAASASXXMMSAMX
 | 
					 | 
				
			||||||
AXMASMAXXAAMAAAAAXXMMMXMSSMSMASMMSAMAMXXAAMXMASXSSSMXSXMMASAMAXXMASMMMMMSAMXSMSMAMAAAAASAMXMMMXMMMAASXSMSSSMMMASAAAMMSMAMAMSXSMSMMASMMAXXAMX
 | 
					 | 
				
			||||||
MAMXXMASMMSMSSSXMMMMSSSXAMAXMAMXMAMMAMMSMMMASMXAMXMXAMXMMMXMASXXXMAXAAAXSMSXSASMSMSMSSMSASXSMMMSMMSMSMSAMAMXXSASMSMSMAAASAMXAXAAAMAMASMMSAMX
 | 
					 | 
				
			||||||
XSSXSAMXAXMAXXMASXSAAAMMMSSMMMSMSAMXXMAAAASXSXMMMAAMMSAXAMAAAXMASXAXSMSMSXSXMAMXXAXAMMXXAMASAMASAAXAXAMAMAMXXMXMAMAAXSSMSASMMMSMSMMSXMAXSMMX
 | 
					 | 
				
			||||||
XAAAMASMSMMXMMMXXAMMXXMAXMAMXMAAMASXMMMSXMMAMXAAMAXSXSXXXMXMMMMMMMMMMMMMMASXMAMMMMMMMSAMXMAMAMXSMMSMMXSMMAMSMMAMMMSMXMAMXXMAMAMAXMASXMXMSAMX
 | 
					 | 
				
			||||||
MMAMMAMAAXMAMMMSSSSXSAMXXAMMAMMSMAMAXXXXXSMSMAXSXSASMMASMMSMSASASMXAMAAAMAMXSAXAAXSSMXSMAMMSXMXXAAAXMXSXSAXAAMSMMAAXAAAMMMSXMASXMASXMSXXXAMX
 | 
					 | 
				
			||||||
AMAXMAXXMASAXAMXAAAASAMSSSXSSSMMMSSXMXXXAMAMXMSAAXASMSMMAAAASASASAMSSSMSMXMXSXXSMMMAMAMMAXMAMXASMXXSXAMAXXXSMMAAMSSSXSMSXAXAMASASXXAXXMMSSMM
 | 
					 | 
				
			||||||
SASMSMSMXAMMMSXMAMMMMAMAAAAAAAAMAMAMXMMMXMXSAMMMSMASAAXXXMMMMMMMMAMMAXAXAASXMXXAASXSMAXMASMMMMMMMSMMMXSMSSMMXSSXMXAXMXAXMMSXSAMAMASMMMMAAXSA
 | 
					 | 
				
			||||||
ASMAMXAXSXXSAXXSAMAXSXMMSMMMSSMMXSAMAAAASMMMMSMAXMAMXMSASMXXXAAAXXMAMMMMMMSAASMMMMAXSXSMMMMAAAXAAAAASAMXAXXAXMASMMMMMMXMAMAXAMMAMXMMAAMSSMAS
 | 
					 | 
				
			||||||
SXMAMSSMSAAMASMMASXMMAMXMXSMXMMAMSASMSMXSAAMXAMXSMMSMMAXMASMSSSSSSXAXAXAAMMMMMXSAMXMXMSAAASMSMSMSXSAMAXMAXSMMXAAXAMAASXMSAXAMSSSSXASXMXAXAMX
 | 
					 | 
				
			||||||
AXMSXXAAMMMMXSASAMXXSAMASXSAAXMAXXMMXAMMMXMMXMSMMAMMMXSAMXSXMXAMAMSSSXSSSXMSAXMAMXMMMASXMMSXMASAMXXMMMSXSAXMASMSSXXMSSMAMMMMXAAAMXXMAXMXSXXM
 | 
					 | 
				
			||||||
MASXMSMMMXXXAMMMXMMMMASAMXMMSMSMSXSSSSMAMMSSSXSMSAMAAXMMSMMAMMXMAMAXMAXXXAASMSXMASAAAXMSSMSAMXSASMSMSAAAAMMMAXSAXXMXMMMAAAAMMMSMAMXMAMSASAMX
 | 
					 | 
				
			||||||
XMXAXAMASXMMMSSMAMXAXXMMSSMAMASASXAAAXMAMXAAMASASMSMSXSASASAMAMSSSXMSMSAMMMMASMXXASXMSAMXAMMMAXAMAAAMMSMMXXMSXMXMASAAXSSSMXXAAAXAMMXSXMAXXAA
 | 
					 | 
				
			||||||
MXSMSMSASAAXAAAMAXMSMMAAAAMAXAMAMMMMMMSASMMMMAMXMASXMAMAMAMMMMMMASXAXAMAMXMMXMAMXMMSMMXMMMMSMSSSMSMMMXMAXXAMXAMXMAXMSMAAMMMSSSSSSXXAMAMAMSSM
 | 
					 | 
				
			||||||
AMAMAMMMXMMMMSSSMSAMASMMSXMXSSMMMMXSXMXAMXASMMSMMMMASXMSMSMXSMAMAMMXMMMMMAMSAMAMXMASXAXXXXAXXAAAMXMSXXSXMSXAXAMMMMMXAXSMXAMXXAXAAXMASAMAAAAM
 | 
					 | 
				
			||||||
SSMSASMMXMAMXAXAMMMSMMAXMMSAMXAXMAASXMMSMMMSAAMAAMSXMSAAAAASAMXMXXMAMAAAMXXSAXMSXMMSMMSMMMMSMMSMMAMXMAMMXMMXSAMAAMASAMXSSMSXMXMXMMSASXSMMSSM
 | 
					 | 
				
			||||||
XAASASAAASXSMMXXMAMXASAMMAMAMSXMMMXMAMAMASASMMSSMMAAXASMMAMMMXAMAMXMMSSSMXASAMSXXSAMXMAXAAMSMXAASXSASXSMAXMXSASMMXAMASAAMXMXASXMXAMXXMXMAAAX
 | 
					 | 
				
			||||||
SMMMAMMMMSMAAAASMSSSXMAMMAMAMXMMSMSSSMASXMAXXXAMXAXXMMXMXMSMXXMMASAAXMAXAMXMXMAAAMASXSASMXXXSSSXMAXASAAXMXMAXXMASMSMAMXMSASMSAXAXSMXXSAMMXSM
 | 
					 | 
				
			||||||
SAXMXMMXMXMMMMXSAAAXMASXSSSMSAMMSAAAXXAMAMXMSMMSSXMMSMASAAAMAMXSASMSMMAMXMAMMSMSMSAMAMMAMMASAMXMASMAMMMMSAMSSXMAMAXMXMSXSAXSMXMSMAMAXMAMSAXX
 | 
					 | 
				
			||||||
MMSMMMSAMMSMXMSMMMMMMAXXAMAMSMSAMMMMMMSAMXAAAASAMASAAMASMXMXMAMMASAAAMMMXXMXAXAAAMMMXMMAAXXMASMXAXMXSAMASXSAAXSSMSMMMMMMMMMMMMAAMAMXSSMMMASA
 | 
					 | 
				
			||||||
MAAXAMSASAAMAMXMAXXAMXSAXSAMXMMMSSXXXAXAXSMSSSMASAMSSMXMXAXXSXXMAMXXSAAAXSSSSMSMSMAXAXSXMXXXMAMMSSXAXAMASXMAMMXMAAXAAAAMASAAAMSMSMSSMASXMMMM
 | 
					 | 
				
			||||||
MSSSXXXXMXMMMXASMSSSSXMMMXXSXXSXAMMMMMMMMXAAMAMAMXMAXXAASXSAAASMMSXMMMMSSMAAXMXMMXMSMMMAXSSMSSSMAXMMSMMMXMASXASMSMSSSSXMAXXSMXAAAMXAMAMXAAMX
 | 
					 | 
				
			||||||
MMAAXSSSMSXMXSASAAAMAAMXSXMMMMMMAXAAAASMMMMMXSMXMXMSSSMXMAXMSMMAMAMASAMXAMMMSSXMAXXXMAMXMAAAAAMMMMSAMAAXXAMXMSMAAXXMAXAMMSAMXSMSMMMXMASXSMMS
 | 
					 | 
				
			||||||
XMMMMAAAASMMAAMMMMMMSSMAMAAAAAXSAMSMSMMAASMSXAXXXAMMAMXAMMMXMXSXMAMXSAXXAMXMMMMMSSMXSMXAXMMMMMMSXAMASXSSSMXXMAMXMSSXMMXMAAAMXMXXAASXMSXMAAXA
 | 
					 | 
				
			||||||
MXSAMXSMMMAMMSXSXXXXAXMAMASXMXMMMMMAMASMMMAAXMMASASMAMSMSAAAMXMXSSSMSXXMSMXMAMXAMAMXMASMXXAMXXAMMASXMAXAASAMXMSAMAMMSMMMMSMMAMMMSMSAXMASXMMA
 | 
					 | 
				
			||||||
AMXXMAAAXSMMXAMAXMAMMMSSXMXMASXSXAMAMAMAAMXMXSAMAMXMAMXXMXXASAMMXAAASXMSAAMSSMMXSAMSMAAMXSSSSMSSMMSAMMMXMMMSAXSAMMSAAASXMAASAMMAMXSAMSXMAMMX
 | 
					 | 
				
			||||||
SSSSMMMSMMSMMMAMSAXXSMAXSAMXAAASMMXAMSSSMMMSAMXXASXMXSXMSSSXSXSSMSMMMAXSMSMXMASAMAMXXSMSAAAAXMAAXASAMSMSXXAMMMSAMAXXSXMAMXXSASMMXAMXMXMSXMXS
 | 
					 | 
				
			||||||
AAAMASMAXMAXAXSXSXMASMAMMMMSAMXSASMXXAAAXXXMASASASAMASAMAAXAMMMAAAAMXMMXMXMASAMASASXAMAMMSMMMMMSMMSAMAASAMMMSASXMXSMMASMMMMMAMAMSAMMMAXXAMMS
 | 
					 | 
				
			||||||
MMMSAMSAMSMSSXXXMAMMXMASXAAAXXXSAMASMMMMMMXSXMMSASMMASAMMMMXMASMMMMMSXMXMAXMMSAAMASMMMXMXMXMASAAAMMMMSSMAMAMMASXSXSASAAMSASMMMXMAMSASXMXAMAM
 | 
					 | 
				
			||||||
XXXMXMMMXAMAXMXSMXMMAMAMMMSMMMAMSMAMAXMSMSASAAAMAMAMASMMSAMXMXMAXXMASAMXSMSMMMMMMXMXXMAMXMAMAXSMMMAAAXAMXMXSMAMASAMXMMMASASXMSSSMASASAMXAMAS
 | 
					 | 
				
			||||||
XSAMXSAMAAMAMMASAXASASAMSAMAAXXXAMXSSMSAAMASXMMSASXMAXMAMASMMSSMMMMAXAMMMMAAAXAXXMASMXAMAMAMSMMMSXSSMSAMSMXMMAMXMAMXXXXXMAMXXAAAXMMMMAMSXSAS
 | 
					 | 
				
			||||||
MMAAAXAMSMMSSMAXMSXSXXAAMAMSAMXMMXXAMXMMSMXMMXXMXXAMMMMXSAMAAMAMSSMMXAMAAXSSMMSMMMXXAXSSMSASXAMAMXAMXSAMMAAMMXXXAMSMMMSMSMMMMMSMMXSAMAMAXMAS
 | 
					 | 
				
			||||||
ASXMSMXMMMAMAMXMXMAMAMSMMMMMSMXSXMXMASMXMASXMASMSSMMSAMXMASMMMAMMMASMMSSSMAXAAMMSASMSMAAASXSMMMASAXXAXAMXSMSMMXMAMAAAAAAAMAAAMXXXAXXXSMSMSAS
 | 
					 | 
				
			||||||
MMMAXMMSMMASXMMAAMXMAXAAXSAAMXAAAXMMMMMXXAMASAXXAAXASMXAMAMASMMSXMXMAAAAXMAMMMMAXAMAAMMMMMMSAMMMSXMMSSSMXXMXASMMMSSSMSMSMSSSSSSMMAMSMXAXAMAS
 | 
					 | 
				
			||||||
MAMAMMASASXSAAMSSMXSASMSXXMSSMSSXMAAAMXMMMMXMSSMSMMXXMMMMAXXMAAMAMXSMMMSMMXSXAMSMSMSMMXXAXAMAMSXMAMXXAMMSAMSXMASAAXMAMAAAXAAAAAXASAAAMAMMMMM
 | 
					 | 
				
			||||||
SAMXSMASXMAMMSMAAMXMXXMAMMAAXAAMAMMSMMAXAMMXAXXAAXXMXSAMSSMASXMMAMASAMXMAMAMMXMXAXAXASMMSSMMAMXASAMMMMSASAMAXXAMMSMMSMMMSMMMMSMSAXSMMMSMMAAX
 | 
					 | 
				
			||||||
SASAAMMMAMXMAMMSSMAXMXMAXMAMMMMSSMAXMSSSXSASXXMXMSSMAMMMAASAMXASXSXSXMASAMASMMSMSMMMMMXAMAMXSMMMSASXAMMASMMMSSXXSXMAAAMAMAXXAAAMMXAXSXMASXSS
 | 
					 | 
				
			||||||
SAMXMAXSXMXMAXAXAMSSMAMSXSASXMAXMMMSAAMAAMAXAASXXAAMXMXMSMMXSSXMASAMMSAMAXAXAAAAAXMAMXMXMASAMAAXXAMMXSMAMAAXMAXMSAMSSSMASMMSAMXMSSMMXAMMMAXM
 | 
					 | 
				
			||||||
MXMMXSXMASXXMMXSAMASMAMXASAXAMSXSAMXMMSMMMMMSAMAMMSAMXSAMAAXXXMXAXASXSMSSMMSMSMSMSXSXMAXSAMASXMSMSXSMSMSMSMSAMXXSAMXMAMASAMXXMASXAXSMSMAMMMS
 | 
					 | 
				
			||||||
SMSXAMMXAMXMSSMSAMAXSASMMMSMSMAASMMXAXXAXAXAMAMMXMAMMASAXMASMMSMMMXMAMXAXSXMAAAMXMXXAMSAMXSMMAAXAMAMXXAMXXXSAXXAMAMXSMMMXAMXXXXSMMMSAAXSAMXA
 | 
					 | 
				
			||||||
MAMMMMAMSSXXAAXSXMSXMXSAXAXMASMMMSSMMMMMMMMXXAMXMMMXSASAMXSXAAAASASMSMXMASMMSMSMAXAXAMXMSASMSMMMMMMSAMMMMXASXMMMSSMMXMAXMMMMSSMSAAAMXMMMAMAM
 | 
					 | 
				
			||||||
MAMAMMSMMAMMXSMXMMMAMMSXMAMSMSXSAMXAAAASAMMXSASXXAAXMAMXMMAMMSMSXASAASAMAMAMAAAMMMMXMMMMMAMXMAMASAAXMXMAMMMMMSXMAAAXXMAMXASXSAASMMXMMMASAMXA
 | 
					 | 
				
			||||||
SAMMSAMASAMSAXMSXSSSMASMSMASMMMMAMSXMSMSASAAXAMXSMSSMMMASXAXAXXMMMMXMXXXXMXMMSMMSMSAMAASMSMXSAMXSMSXXAXASAMMASAMSXMMSMAXSAMSSMMMASXSAMASAMMS
 | 
					 | 
				
			||||||
SMSAMXSASAMXASASAAAAMAMAAMAMAAXXMMSAMXMSAMXSMAMXXMAAXAMAXSMMMMMSAAAXXSSMSMSXMAAXAASASMMSAXAAXXMMXMMMSXSASASMAMAMXMSASMAMMAMXMXMASMAAMMASAMAA
 | 
					 | 
				
			||||||
XAAMSMMXSMSMAMAMMMMMXXMMMMASMMSXMASAMMMMXSAMXSMSAMXSSMMSMMXXSAAXSMSXMXAAAASMSSSMMXMMXMAMXMMMSSSMSAMXAASXSXMMMXMMMAMASMMXSMMXSXXMASXMXSASMMXS
 | 
					 | 
				
			||||||
MMMAMXMMSASXXMSMSXXXAMSMMSMSMASXMAMAMAAAXMASXAMAMXAAAXAXAXMASMSXMXAXSSMMMXMAXXAMXMSSXMXMASXMAXAAMAMMMXMAMXSXMASAMAMAMASMMAAAXXMMAMXXXMMMASMA
 | 
					 | 
				
			||||||
XMMAMAAAMAMMMMXAXSSMMMAAXAMXMAMMMMSSXSMSSMSSMMMAMMMMMMAXSXMAMXMASMMAXAMXSSXSMSSMSAAASXMSASAMSXMMSAMAMSMSMASASAMAMXMXSAMASMMXSASMSSSMSSMSAMXS
 | 
					 | 
				
			||||||
MAMAMXMMMAMAAAMMMXMASXMSSXMAMMMXAAAAXXXMXMAMAXSXSASASMXXMXMASASMMAXMSAMASMAMAAAAAXSMMXXMASXMMAXMMASXSXXAMASAMXSXMSXXMAMXMAAXSAMAXAAAAAMMSMXM
 | 
					 | 
				
			||||||
ASXSSXSASMSSMXSAMXMSMMAAAASMSMSSSSSMXMAMSMMMSMMASAMAXMAMMAXMSASMSSMXSAMXSMAMMMMSMAXXSXSMMSAMSXMSSMMMMXMMMAMXMASAAXAMSSXMMMMXMMMXMSMMMSMAXMMX
 | 
					 | 
				
			||||||
SXAAAXSAMAAAAMSXMMSXAMMMXMXAAAAAXAMXAMAMXASAXXMAMAMSMSAASAMXMMMAAAMASAMXSMMSXXXAMASAMXXAAMAMMSMAAASXSAMXMMSMMASMMMXMAMAMSAMXXMMSXMASXMMSMMSM
 | 
					 | 
				
			||||||
MMMMMMMMMMMMMMMAMSMMSMASASMSMMMMMMMSMSAXSAMXSMMMMMMXASXXMMSAAASMSSMASAMXMAMXMXMAAXMMMSSMMSXMAAMSSMXASXXAXAXAMAMAXASMSXSMSMSMSSXMASMMMMAMAASA
 | 
					 | 
				
			||||||
AAXAXXAXXXSASASAMAMMMMMXAAAXMASAAAMXAAMAAAMAXMASAAAMXMSXAAMMXMXXMAMASAMMSAMMMASXMASXAXAMXAAMXSMMAASMMMSAXSSMMSSMMMSXMAXAMMAAAMASMMXASMAMMMMS
 | 
					 | 
				
			||||||
SSSMSSMSMMSASMXAXXSAXXSMSMSMSASMSMSMMMMXMAXXXSASXSMXMAMMMMSSXMMMSXMMMAMASMSXSASAXASMSSXMMSXMAMASMMSAAXMSMAAAAMAMXMMAMAMAMSMMASXXAXSAMMSSMXAX
 | 
					 | 
				
			||||||
XAAXAAMAAMMMMXMXSAMXSXMAAAAMMMSAXASAMXXMXXAMXSXMAXAAMAMAAXAMMSAAXXMXSAMXSAAAMXSAMXSAAAAXXMAMASAMMASMMMAMMSMMSSSMSASXMSSXMXXMAMMSSMMXXAXAAMMX
 | 
					 | 
				
			||||||
MSMMSSMMMSAAAAXMAXMAMMMSMMMSAAMMMAMAXXSMSMSMAMASXMSXSASMSMMSASMSMSAASMMMMMMSMXSASXMMMSXMASAMAMMMMAXASXXSAAAAAAMASAAXAXAAMXSMSSMAMAXMASMMMSSS
 | 
					 | 
				
			||||||
AAXAAAAXXSMMSSSXAMSAMXAAAAXSASAMMAMSAMXAAAAMASAMAAXMAXSAAASMMSAXAMMXMAMSAMXAXMSAMMAAAAXAXSXMMSXXMASAMMAMXSSMMSMAMSMAMMSMMSAMXAMASMMASXAAAAAA
 | 
					 | 
				
			||||||
SSSSSSMMXMAMMMXMAMSMMMSSSMXXMMMXSXSMSXMAMSMSXMXSMMMXMASXXSMSMMMMXMAMXAXSXMSAMXMXMSSMSXMSAMXASMXMAMAMXMMMMMAMXXMXXAXXXAXSXXXMSAMAXXASMSSMMMSM
 | 
					 | 
				
			||||||
@ -1,163 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// var log = aoc.Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type result struct {
 | 
					 | 
				
			||||||
	valuePT1 int
 | 
					 | 
				
			||||||
	valuePT2 int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type record struct {
 | 
					 | 
				
			||||||
	p aoc.Point[int]
 | 
					 | 
				
			||||||
	d [2]int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func run(scan *bufio.Scanner) (*result, error) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	m := make([][]rune, 0, 1000)
 | 
					 | 
				
			||||||
	var records []record
 | 
					 | 
				
			||||||
	var records2 []record
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for scan.Scan() {
 | 
					 | 
				
			||||||
		txt := scan.Text()
 | 
					 | 
				
			||||||
		m = append(m, []rune(txt))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for x, row := range m {
 | 
					 | 
				
			||||||
		for y, c := range row {
 | 
					 | 
				
			||||||
			if c == 'X' {
 | 
					 | 
				
			||||||
				rs := search1(record{
 | 
					 | 
				
			||||||
					p: aoc.Point[int]{x, y},
 | 
					 | 
				
			||||||
				}, m)
 | 
					 | 
				
			||||||
				records = append(records, rs...)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if c == 'A' {
 | 
					 | 
				
			||||||
				rs := search2(record{
 | 
					 | 
				
			||||||
					p: aoc.Point[int]{x, y},
 | 
					 | 
				
			||||||
				}, m)
 | 
					 | 
				
			||||||
				if len(rs) == 2 {
 | 
					 | 
				
			||||||
					records2 = append(records2, rs...)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, r := range records2 {
 | 
					 | 
				
			||||||
		fmt.Println(r)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &result{len(records), len(records2)/2}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func search1(r record, m [][]rune) []record {
 | 
					 | 
				
			||||||
	var ds = [][2]int{
 | 
					 | 
				
			||||||
		{1, 0},   // up
 | 
					 | 
				
			||||||
		{0, 1},   // right
 | 
					 | 
				
			||||||
		{-1, 0},  // down
 | 
					 | 
				
			||||||
		{0, -1},  // left
 | 
					 | 
				
			||||||
		{1, 1},   // up-right
 | 
					 | 
				
			||||||
		{1, -1},  // up-left
 | 
					 | 
				
			||||||
		{-1, 1},  // down-right
 | 
					 | 
				
			||||||
		{-1, -1}, // down-left
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var records []record
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, d := range ds {
 | 
					 | 
				
			||||||
		p := r.p
 | 
					 | 
				
			||||||
		if !check1(m, p, d) {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		records = append(records, record{
 | 
					 | 
				
			||||||
			p: p,
 | 
					 | 
				
			||||||
			d: d,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return records
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func check1(m [][]rune, p aoc.Point[int], d [2]int) bool {
 | 
					 | 
				
			||||||
	for _, r := range []rune{'M', 'A', 'S'} {
 | 
					 | 
				
			||||||
		p[0] += d[0]
 | 
					 | 
				
			||||||
		p[1] += d[1]
 | 
					 | 
				
			||||||
		if p[0] < 0 || p[0] >= len(m) {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if p[1] < 0 || p[1] >= len(m[0]) {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if m[p[0]][p[1]] != r {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func search2(r record, m [][]rune) []record {
 | 
					 | 
				
			||||||
	var ds = [][2]int{
 | 
					 | 
				
			||||||
		{1, 1},   // up-right
 | 
					 | 
				
			||||||
		{1, -1},  // up-left
 | 
					 | 
				
			||||||
		{-1, 1},  // down-right
 | 
					 | 
				
			||||||
		{-1, -1}, // down-left
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var records []record
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, d := range ds {
 | 
					 | 
				
			||||||
		p := r.p
 | 
					 | 
				
			||||||
		if !check2(m, p, d) {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		records = append(records, record{
 | 
					 | 
				
			||||||
			p: p,
 | 
					 | 
				
			||||||
			d: d,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return records
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func check2(m [][]rune, p aoc.Point[int], d [2]int) bool {
 | 
					 | 
				
			||||||
	p0 := p[0] - d[0]
 | 
					 | 
				
			||||||
	p1 := p[1] - d[1]
 | 
					 | 
				
			||||||
	if p0 < 0 || p0 >= len(m) {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if p1 < 0 || p1 >= len(m[0]) {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if m[p0][p1] != 'M' {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p0 = p[0] + d[0]
 | 
					 | 
				
			||||||
	p1 = p[1] + d[1]
 | 
					 | 
				
			||||||
	if p0 < 0 || p0 >= len(m) {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if p1 < 0 || p1 >= len(m[0]) {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if m[p0][p1] != 'S' {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,41 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/matryer/is"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed example.txt
 | 
					 | 
				
			||||||
var example []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed input.txt
 | 
					 | 
				
			||||||
var input []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestExample(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 18)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 9)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestSolution(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 2536)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 1875)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,28 +0,0 @@
 | 
				
			|||||||
47|53
 | 
					 | 
				
			||||||
97|13
 | 
					 | 
				
			||||||
97|61
 | 
					 | 
				
			||||||
97|47
 | 
					 | 
				
			||||||
75|29
 | 
					 | 
				
			||||||
61|13
 | 
					 | 
				
			||||||
75|53
 | 
					 | 
				
			||||||
29|13
 | 
					 | 
				
			||||||
97|29
 | 
					 | 
				
			||||||
53|29
 | 
					 | 
				
			||||||
61|53
 | 
					 | 
				
			||||||
97|53
 | 
					 | 
				
			||||||
61|29
 | 
					 | 
				
			||||||
47|13
 | 
					 | 
				
			||||||
75|47
 | 
					 | 
				
			||||||
97|75
 | 
					 | 
				
			||||||
47|61
 | 
					 | 
				
			||||||
75|61
 | 
					 | 
				
			||||||
47|29
 | 
					 | 
				
			||||||
75|13
 | 
					 | 
				
			||||||
53|13
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
75,47,61,53,29
 | 
					 | 
				
			||||||
97,61,53,29,13
 | 
					 | 
				
			||||||
75,29,13
 | 
					 | 
				
			||||||
75,97,47,61,53
 | 
					 | 
				
			||||||
61,13,29
 | 
					 | 
				
			||||||
97,13,75,29,47
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,83 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// var log = aoc.Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type result struct {
 | 
					 | 
				
			||||||
	valuePT1 int
 | 
					 | 
				
			||||||
	valuePT2 int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func run(scan *bufio.Scanner) (*result, error) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ordering := make(map[int]aoc.Set[int])
 | 
					 | 
				
			||||||
	var updates [][]int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for scan.Scan() {
 | 
					 | 
				
			||||||
		txt := scan.Text()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if txt == "" {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var key, val int
 | 
					 | 
				
			||||||
		_, err := fmt.Sscanf(txt, "%d|%d", &val, &key)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if _, ok := ordering[key]; !ok {
 | 
					 | 
				
			||||||
			ordering[key] = aoc.NewSet[int]()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		s := ordering[key]
 | 
					 | 
				
			||||||
		s.Add(val)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var sum int
 | 
					 | 
				
			||||||
	var sum2 int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
outer:
 | 
					 | 
				
			||||||
	for scan.Scan() {
 | 
					 | 
				
			||||||
		txt := scan.Text()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		arr := aoc.SliceMap(aoc.Atoi, strings.Split(txt, ",")...)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for i, v := range arr {
 | 
					 | 
				
			||||||
			m, ok := ordering[v]
 | 
					 | 
				
			||||||
			if (i > 0 && !ok) || !m.ContainsAll(arr[:i]...) {
 | 
					 | 
				
			||||||
				sort.SliceStable(arr, func(i, j int) bool {
 | 
					 | 
				
			||||||
					if a, ok := ordering[arr[i]]; ok && a.Has(arr[j]) {
 | 
					 | 
				
			||||||
						return true
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					if b, ok := ordering[arr[j]]; ok && b.Has(arr[i]) {
 | 
					 | 
				
			||||||
						return false
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					return false
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				sum2 += arr[len(arr)/2]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				continue outer
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sum += arr[len(arr)/2]
 | 
					 | 
				
			||||||
		updates = append(updates, arr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &result{sum, sum2}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,41 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/matryer/is"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed example.txt
 | 
					 | 
				
			||||||
var example []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed input.txt
 | 
					 | 
				
			||||||
var input []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestExample(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 143)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 123)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestSolution(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 7307)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 4713)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
....#.....
 | 
					 | 
				
			||||||
.........#
 | 
					 | 
				
			||||||
..........
 | 
					 | 
				
			||||||
..#.......
 | 
					 | 
				
			||||||
.......#..
 | 
					 | 
				
			||||||
..........
 | 
					 | 
				
			||||||
.#..^.....
 | 
					 | 
				
			||||||
........#.
 | 
					 | 
				
			||||||
#.........
 | 
					 | 
				
			||||||
......#...
 | 
					 | 
				
			||||||
@ -1,130 +0,0 @@
 | 
				
			|||||||
........#........................................#......#........#................................................................
 | 
					 | 
				
			||||||
....................................#......#.....#............#.............#..........#..........................................
 | 
					 | 
				
			||||||
......................#.......................................................#...................................................
 | 
					 | 
				
			||||||
.......#..#..#....#...#...#....#..............#......#.......#...#................#.......#.......................................
 | 
					 | 
				
			||||||
......................#....##...#.......#....#.......................................#....................#.......................
 | 
					 | 
				
			||||||
...#............................#........................................#..........................#.....................#.......
 | 
					 | 
				
			||||||
....................#............#...............#......#.........#...........#...................................................
 | 
					 | 
				
			||||||
............................#......#...#................#.............#...........................................................
 | 
					 | 
				
			||||||
.....#..#.........#....................#......................................................#........................#.........#
 | 
					 | 
				
			||||||
.........#..##.#.........#.............................................#...........#........#....................##...............
 | 
					 | 
				
			||||||
...............#....#.........................##......#.....................#..............................................#......
 | 
					 | 
				
			||||||
..................##...................................#...........#........#....#.............#..................#........#.#....
 | 
					 | 
				
			||||||
....................................#...................#..............................#............#.............................
 | 
					 | 
				
			||||||
.........#.....#................#..........................................#...................................#..............#...
 | 
					 | 
				
			||||||
...#....................#...................................#..##...................#.......#......................###.........#..
 | 
					 | 
				
			||||||
....................#............#....#.##....#.........#......#...#........................#.......................#..........#..
 | 
					 | 
				
			||||||
..............#...................................................................................#....................#..........
 | 
					 | 
				
			||||||
.........#................#..............................#............................#...#.................#...............#.....
 | 
					 | 
				
			||||||
............................................................................................#...#............................#....
 | 
					 | 
				
			||||||
............#....................#................................#....#...............................#....#.....................
 | 
					 | 
				
			||||||
........................................#.........#..................................................#..#..................#......
 | 
					 | 
				
			||||||
.............#.#............................#..#.....#............................................#....#..........................
 | 
					 | 
				
			||||||
................................................................................................#.........#..#..............#..#..
 | 
					 | 
				
			||||||
...........#..........#.#..#................#.#..#...#.........#..........................................#..........#..#.........
 | 
					 | 
				
			||||||
.............................#....................#.......#....#.....#....#......#....................#..#...............##.......
 | 
					 | 
				
			||||||
..........#..............................................................................#....#.........#..#................#.....
 | 
					 | 
				
			||||||
..#..#...............................................................#.......#........#...........................#...............
 | 
					 | 
				
			||||||
...........................................................................#...##....................#.#....##....................
 | 
					 | 
				
			||||||
.......................................#...............................................#.....................#.........#..........
 | 
					 | 
				
			||||||
.......................................................#.......#....#................#.....................................#......
 | 
					 | 
				
			||||||
.............#................#...................#.................#....................#..................#.#.........#.........
 | 
					 | 
				
			||||||
.....................................................................#.....................................#......................
 | 
					 | 
				
			||||||
........................#..........................................#....#..#.#..........................................#.........
 | 
					 | 
				
			||||||
............#.......#..................#.................................................#..............#.......................#.
 | 
					 | 
				
			||||||
.........................................................#...............#...#....#...........#.................................#.
 | 
					 | 
				
			||||||
.........................#..........................#..#........................................................#.................
 | 
					 | 
				
			||||||
...............#....................................#.......#......................................#............#.................
 | 
					 | 
				
			||||||
.#......................................................................................................#.........................
 | 
					 | 
				
			||||||
#...#........................................................#.................#....#....................#...........#............
 | 
					 | 
				
			||||||
..#.........#................................................................#................................#.............#.....
 | 
					 | 
				
			||||||
..................................#.........................................................................#................#....
 | 
					 | 
				
			||||||
..............#..............................................#........#..................................#........................
 | 
					 | 
				
			||||||
......#............................................#.................................#............................#...............
 | 
					 | 
				
			||||||
.......##..#.......................##............#...#...................#.#..........................................##..........
 | 
					 | 
				
			||||||
.#......#.....................................................................#..#..........................#......#.............#
 | 
					 | 
				
			||||||
.................#.....................#........##..#.........#........#................#.........................................
 | 
					 | 
				
			||||||
...........#.....#..........#........#............................................................................................
 | 
					 | 
				
			||||||
.........................#......#.......................................#..............................#..........................
 | 
					 | 
				
			||||||
............#............................................................#..............#..............................#..........
 | 
					 | 
				
			||||||
..................#.........#...........................................................................................#.........
 | 
					 | 
				
			||||||
#.#..................................#....................#......................#.............#.................................#
 | 
					 | 
				
			||||||
....#................#.................#...................#...........#......................................#...................
 | 
					 | 
				
			||||||
................#........................................................................................#....#.#.......#.....##..
 | 
					 | 
				
			||||||
..........#...#.......................................#........#.......................................#...#......................
 | 
					 | 
				
			||||||
.......#..##........................#......##.........................#.........#.......#.............................#.....#.....
 | 
					 | 
				
			||||||
................#...............................................#....#..........#.....#.........#.........#.........#.............
 | 
					 | 
				
			||||||
...............................#............#....................................#......#......................................#..
 | 
					 | 
				
			||||||
.#..#..................#............................................#....#............#...............##...#..........#...........
 | 
					 | 
				
			||||||
....#.............................................................................................................................
 | 
					 | 
				
			||||||
.............................................................#...........................#..........#.............................
 | 
					 | 
				
			||||||
.#........#..................#.....#.............#.....................................................#...#........#...........#.
 | 
					 | 
				
			||||||
.......................#........................................#.....#............................#.#..................#.........
 | 
					 | 
				
			||||||
................#....#................#.......#............................#.......#.................#............................
 | 
					 | 
				
			||||||
....#.........#....#........#.....................#........................#............#.........................................
 | 
					 | 
				
			||||||
.......#.......#.....................................................................##...........#...............................
 | 
					 | 
				
			||||||
...........#.........................................................#..........#............#....................................
 | 
					 | 
				
			||||||
..................#.............................#.......................................................................#.........
 | 
					 | 
				
			||||||
................#.....#........#.....#...#..........#.....................................#.....#........................#........
 | 
					 | 
				
			||||||
..........................................#.........#...........#.................................................................
 | 
					 | 
				
			||||||
...#.......................................................................................................#......................
 | 
					 | 
				
			||||||
....#..............#...........#..................................................#.................#.................#...........
 | 
					 | 
				
			||||||
.#................#.....#.#.................................................................#.........................#...........
 | 
					 | 
				
			||||||
............#.........................##....................................#..............#......................................
 | 
					 | 
				
			||||||
...##...........#...#............#..........................................................................#.....................
 | 
					 | 
				
			||||||
............................................#......................#......#.......................................................
 | 
					 | 
				
			||||||
............#............................................................................................................#........
 | 
					 | 
				
			||||||
...................##..............#.#....#.##...................................................#..................#.............
 | 
					 | 
				
			||||||
..#...................................................................................#.........#.........................#.....#.
 | 
					 | 
				
			||||||
........................#..............................................#......#................................................#..
 | 
					 | 
				
			||||||
................#............#............................#.#...................#.....................#...........................
 | 
					 | 
				
			||||||
..................#......#................#.#......................#...................#...#......................................
 | 
					 | 
				
			||||||
..#................................................##...................................................................#.........
 | 
					 | 
				
			||||||
...........................#......................................................................#......#...#......#.............
 | 
					 | 
				
			||||||
........................#...#........#......#.......#..........#.............................#........#.....#.....................
 | 
					 | 
				
			||||||
.................................................#..............................................#......#.....#....................
 | 
					 | 
				
			||||||
.....#....#.................#......#........#.#..............^...........................#...................#..#.................
 | 
					 | 
				
			||||||
.............................................................................#................................#...................
 | 
					 | 
				
			||||||
#..........................#..#..............#.......#..........................#.................................................
 | 
					 | 
				
			||||||
............#.............................................................................#...................#...................
 | 
					 | 
				
			||||||
..................#.............................#.........................................#................#.........#......#.....
 | 
					 | 
				
			||||||
...#...............................#.....#......#............###.#.#.....................................#....#.............#.....
 | 
					 | 
				
			||||||
...........#...........#...........................#..............................................................................
 | 
					 | 
				
			||||||
............#..........................................#.....#.............#..........................#....................#.....#
 | 
					 | 
				
			||||||
........................#......#..#............................#.......................................................#..........
 | 
					 | 
				
			||||||
..#...#...#.......#.#..........................................#.............#.........#....#..................#...........#......
 | 
					 | 
				
			||||||
..................#.......#.....................................................................................#........#........
 | 
					 | 
				
			||||||
......##................#...........................................#..............##.................................#...........
 | 
					 | 
				
			||||||
.................#................................................................................#.#....................#........
 | 
					 | 
				
			||||||
....................#.........#..........#...............#...#...#.#.#............................................................
 | 
					 | 
				
			||||||
#..................#.#..........#..#...................................................................................#..........
 | 
					 | 
				
			||||||
..........#........................................................#..........##..........................#..##...................
 | 
					 | 
				
			||||||
...........#...................................................................#..................................................
 | 
					 | 
				
			||||||
..................#........#............................................#..................#....#.......................#..#......
 | 
					 | 
				
			||||||
............#...................#......#..........................................................................................
 | 
					 | 
				
			||||||
...........................#.....##..........#.#..............#......................#.............#.......#...........#..........
 | 
					 | 
				
			||||||
............#..................................................#.......#.........#.#..................#..............##...........
 | 
					 | 
				
			||||||
#..................................................#...#......#..#......................#.............#........#............#.....
 | 
					 | 
				
			||||||
....#..................#..........#.........#.........................................#..................#................#.......
 | 
					 | 
				
			||||||
...#.................#.............................................................................#....................#.........
 | 
					 | 
				
			||||||
..........#.................................................................#............#....................#.#.#.....#.........
 | 
					 | 
				
			||||||
.....................#......................#...........#........#................................................................
 | 
					 | 
				
			||||||
.....#.......................................................................#......................#...#......#..................
 | 
					 | 
				
			||||||
.............##........#.....................#...........##........#............#.....#.....................#...............#.....
 | 
					 | 
				
			||||||
.....#.........#....#.................#....#...........#.......##..........#.........#.#......................................#...
 | 
					 | 
				
			||||||
.......#..................##.......#...#.#...#...................................#.......................................#.....#..
 | 
					 | 
				
			||||||
...............#.......#.................#........................................................................................
 | 
					 | 
				
			||||||
......#.......#.....#...............................#...........#.......#......................##...#....#........................
 | 
					 | 
				
			||||||
.##..........................##..................##................#..#....#...##.................................................
 | 
					 | 
				
			||||||
........#..............................#.#......#........#...............#....#........#.#........................................
 | 
					 | 
				
			||||||
...............................#..#.....................#.#...................#...................................................
 | 
					 | 
				
			||||||
.....................#.................................................##...#.......#.................##...............#.......#..
 | 
					 | 
				
			||||||
.............#..........................#.................................#..............#.......#..........#........#............
 | 
					 | 
				
			||||||
.........................................#...................#.........................................................#..........
 | 
					 | 
				
			||||||
...............................#..........#..............................#............#.....#.....................................
 | 
					 | 
				
			||||||
.............#..........................#....................#................................#...#............#..................
 | 
					 | 
				
			||||||
....#......#........#.......#......#................................................#...#......................................##.
 | 
					 | 
				
			||||||
..#...................................#........#.....................................#...#......#.........#..#..........#.........
 | 
					 | 
				
			||||||
.......#.........#................................................................................................................
 | 
					 | 
				
			||||||
...........#...............................##.........................................#..#....................#.....#.#.......##..
 | 
					 | 
				
			||||||
.........................#..#...............#............................#.............#..........................#..............#
 | 
					 | 
				
			||||||
@ -1,147 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// var log = aoc.Log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type result struct {
 | 
					 | 
				
			||||||
	valuePT1 int
 | 
					 | 
				
			||||||
	valuePT2 int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func run(scan *bufio.Scanner) (*result, error) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var start aoc.Point[int]
 | 
					 | 
				
			||||||
	var m [][]rune
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for scan.Scan() {
 | 
					 | 
				
			||||||
		txt := scan.Text()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if txt == "" {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		m = append(m, []rune(txt))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for i, c := range txt {
 | 
					 | 
				
			||||||
			if c == '^' {
 | 
					 | 
				
			||||||
				start = aoc.Point[int]{len(m) - 1, i}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sum, positions, _ := runPT1(m, start)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	loops := runPT2(m, start, positions)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &result{sum, loops}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func isOutOfBounds(p, topRight, bottomLeft aoc.Point[int]) bool {
 | 
					 | 
				
			||||||
	return p[0] < topRight[0] ||
 | 
					 | 
				
			||||||
		p[0] > bottomLeft[0] ||
 | 
					 | 
				
			||||||
		p[1] < topRight[1] ||
 | 
					 | 
				
			||||||
		p[1] > bottomLeft[1]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func printMap(m [][]rune, o aoc.Point[int]) {
 | 
					 | 
				
			||||||
	for i, row := range m {
 | 
					 | 
				
			||||||
		if i == o[0] {
 | 
					 | 
				
			||||||
			row[o[1]] = 'O'
 | 
					 | 
				
			||||||
		} 
 | 
					 | 
				
			||||||
		println(string(row))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	println()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func runPT1(m [][]rune, start aoc.Point[int]) (int, []aoc.Point[int], bool) {
 | 
					 | 
				
			||||||
	m = copyMap(m)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	topRight := aoc.Point[int]{0, 0}
 | 
					 | 
				
			||||||
	bottomLeft := aoc.Point[int]{len(m) - 1, len(m[0]) - 1}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	directions := []aoc.Point[int]{
 | 
					 | 
				
			||||||
		{-1, 0}, // up
 | 
					 | 
				
			||||||
		{0, 1},  // right
 | 
					 | 
				
			||||||
		{1, 0},  // down
 | 
					 | 
				
			||||||
		{0, -1}, // left
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	d := 0
 | 
					 | 
				
			||||||
	current := start
 | 
					 | 
				
			||||||
	var loopStart [3]int
 | 
					 | 
				
			||||||
	var paths = aoc.NewSet[[3]int]()
 | 
					 | 
				
			||||||
	for !isOutOfBounds(current, topRight, bottomLeft) {
 | 
					 | 
				
			||||||
		m[current[0]][current[1]] = 'X'
 | 
					 | 
				
			||||||
		next := current.Add(directions[d])
 | 
					 | 
				
			||||||
		if isOutOfBounds(next, topRight, bottomLeft) {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if m[next[0]][next[1]] == '#' {
 | 
					 | 
				
			||||||
			d = (d + 1) % 4
 | 
					 | 
				
			||||||
			pt := [3]int{current[0], current[1], d}
 | 
					 | 
				
			||||||
			if paths.Has(pt) {
 | 
					 | 
				
			||||||
				if loopStart == pt {
 | 
					 | 
				
			||||||
					return 0, nil, true
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if loopStart == [3]int{} {
 | 
					 | 
				
			||||||
					loopStart = pt					
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			paths.Add(pt)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		current = next
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var sum int
 | 
					 | 
				
			||||||
	var points []aoc.Point[int]
 | 
					 | 
				
			||||||
	for y, row := range m {
 | 
					 | 
				
			||||||
		for x, v := range row {
 | 
					 | 
				
			||||||
			if v == 'X' {
 | 
					 | 
				
			||||||
				points = append(points, aoc.Point[int]{x, y})
 | 
					 | 
				
			||||||
				sum++
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return sum, points, false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func runPT2(m [][]rune, start aoc.Point[int], points []aoc.Point[int]) int {
 | 
					 | 
				
			||||||
	sum := 0
 | 
					 | 
				
			||||||
	for _, p := range points {
 | 
					 | 
				
			||||||
		cm := copyMap(m)
 | 
					 | 
				
			||||||
		cm[p[0]][p[1]] = '#'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		_, _, isOOB :=runPT1(cm, start)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if !isOOB {
 | 
					 | 
				
			||||||
			printMap(cm, start)
 | 
					 | 
				
			||||||
			sum++
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return sum
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func copyMap(m [][]rune) [][]rune {
 | 
					 | 
				
			||||||
	newM := make([][]rune, len(m))
 | 
					 | 
				
			||||||
	for i, row := range m {
 | 
					 | 
				
			||||||
		newM[i] = make([]rune, len(row))
 | 
					 | 
				
			||||||
		copy(newM[i], row)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return newM
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,43 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/matryer/is"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed example.txt
 | 
					 | 
				
			||||||
var example []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//go:embed input.txt
 | 
					 | 
				
			||||||
var input []byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestExample(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 41)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 6)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestSolution(t *testing.T) {
 | 
					 | 
				
			||||||
	is := is.New(t)
 | 
					 | 
				
			||||||
	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := run(scan)
 | 
					 | 
				
			||||||
	is.NoErr(err)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log(result)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT1, 5329)
 | 
					 | 
				
			||||||
	is.True(result.valuePT2 > 897)
 | 
					 | 
				
			||||||
	is.Equal(result.valuePT2, 0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										24
									
								
								aoc_test.go
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								aoc_test.go
									
									
									
									
									
								
							@ -9,6 +9,7 @@ import (
 | 
				
			|||||||
	aoc "go.sour.is/advent-of-code"
 | 
						aoc "go.sour.is/advent-of-code"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestList(t *testing.T) {
 | 
					func TestList(t *testing.T) {
 | 
				
			||||||
	is := is.New(t)
 | 
						is := is.New(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,6 +56,7 @@ func TestPriorityQueue(t *testing.T) {
 | 
				
			|||||||
	is.True(v == nil)
 | 
						is.True(v == nil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ExamplePriorityQueue() {
 | 
					func ExamplePriorityQueue() {
 | 
				
			||||||
	type memo struct {
 | 
						type memo struct {
 | 
				
			||||||
		pt    int
 | 
							pt    int
 | 
				
			||||||
@ -72,7 +74,7 @@ func ExamplePriorityQueue() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pq := aoc.PriorityQueue(less)
 | 
						pq := aoc.PriorityQueue(less)
 | 
				
			||||||
	visited := aoc.NewSet([]int{}...)
 | 
						visited := aoc.Set([]int{}...)
 | 
				
			||||||
	dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
 | 
						dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dist.Set(0, 0)
 | 
						dist.Set(0, 0)
 | 
				
			||||||
@ -115,7 +117,25 @@ func ExamplePriorityQueue() {
 | 
				
			|||||||
	// point 5 is 22 steps away.
 | 
						// point 5 is 22 steps away.
 | 
				
			||||||
	// point 6 is 19 steps away.
 | 
						// point 6 is 19 steps away.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					func TestGraph(t *testing.T) {
 | 
				
			||||||
 | 
						is := is.New(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var adjacencyList = map[int][]int{
 | 
				
			||||||
 | 
							2: {3, 5, 1},
 | 
				
			||||||
 | 
							1: {2, 4},
 | 
				
			||||||
 | 
							3: {6, 2},
 | 
				
			||||||
 | 
							4: {1, 5, 7},
 | 
				
			||||||
 | 
							5: {2, 6, 8, 4},
 | 
				
			||||||
 | 
							6: {3, 0, 9, 5},
 | 
				
			||||||
 | 
							7: {4, 8},
 | 
				
			||||||
 | 
							8: {5, 9, 7},
 | 
				
			||||||
 | 
							9: {6, 0, 8},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						g := aoc.Graph(aoc.WithAdjacencyList[int, int](adjacencyList))
 | 
				
			||||||
 | 
						is.Equal(g.Neighbors(1), []int{2, 4})
 | 
				
			||||||
 | 
						is.Equal(map[int][]int(g.AdjacencyList()), adjacencyList)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ExampleFibHeap() {
 | 
					func ExampleFibHeap() {
 | 
				
			||||||
	type memo struct {
 | 
						type memo struct {
 | 
				
			||||||
@ -134,7 +154,7 @@ func ExampleFibHeap() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pq := aoc.FibHeap(less)
 | 
						pq := aoc.FibHeap(less)
 | 
				
			||||||
	visited := aoc.NewSet([]int{}...)
 | 
						visited := aoc.Set([]int{}...)
 | 
				
			||||||
	dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
 | 
						dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dist.Set(0, 0)
 | 
						dist.Set(0, 0)
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,6 @@ import (
 | 
				
			|||||||
	"bufio"
 | 
						"bufio"
 | 
				
			||||||
	_ "embed"
 | 
						_ "embed"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"slices"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	aoc "go.sour.is/advent-of-code"
 | 
						aoc "go.sour.is/advent-of-code"
 | 
				
			||||||
@ -63,7 +62,7 @@ func run(scan *bufio.Scanner) (*result, error) {
 | 
				
			|||||||
					func(i int, v int, counts [3]int) [3]int {
 | 
										func(i int, v int, counts [3]int) [3]int {
 | 
				
			||||||
						counts[v]++
 | 
											counts[v]++
 | 
				
			||||||
						return counts
 | 
											return counts
 | 
				
			||||||
					}, [3]int{}, slices.Values(maps.Values(memo)))
 | 
										}, [3]int{}, maps.Values(memo)...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// fmt.Println(i, counts)
 | 
									// fmt.Println(i, counts)
 | 
				
			||||||
				i = 1_000_000_000 - (1_000_000_000-counts[0]-counts[1])%counts[2]
 | 
									i = 1_000_000_000 - (1_000_000_000-counts[0]-counts[1])%counts[2]
 | 
				
			||||||
@ -32,14 +32,14 @@ func run(scan *bufio.Scanner) (*result, error) {
 | 
				
			|||||||
		r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int {
 | 
							r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int {
 | 
				
			||||||
			sum += hash(t)
 | 
								sum += hash(t)
 | 
				
			||||||
			return sum
 | 
								return sum
 | 
				
			||||||
		}, 0, slices.Values(ops))
 | 
							}, 0, ops...)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var boxen boxes
 | 
						var boxen boxes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
 | 
						boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
 | 
				
			||||||
		return b.Op(op)
 | 
							return b.Op(op)
 | 
				
			||||||
	}, boxen, slices.Values(ops))
 | 
						}, boxen, ops...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.valuePT2 = boxen.Sum()
 | 
						r.valuePT2 = boxen.Sum()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user