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"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func TestList(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
@ -55,6 +56,7 @@ func TestPriorityQueue(t *testing.T) {
 | 
			
		||||
	is.True(v == nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func ExamplePriorityQueue() {
 | 
			
		||||
	type memo struct {
 | 
			
		||||
		pt    int
 | 
			
		||||
@ -72,7 +74,7 @@ func ExamplePriorityQueue() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pq := aoc.PriorityQueue(less)
 | 
			
		||||
	visited := aoc.NewSet([]int{}...)
 | 
			
		||||
	visited := aoc.Set([]int{}...)
 | 
			
		||||
	dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
 | 
			
		||||
 | 
			
		||||
	dist.Set(0, 0)
 | 
			
		||||
@ -115,7 +117,25 @@ func ExamplePriorityQueue() {
 | 
			
		||||
	// point 5 is 22 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() {
 | 
			
		||||
	type memo struct {
 | 
			
		||||
@ -134,7 +154,7 @@ func ExampleFibHeap() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pq := aoc.FibHeap(less)
 | 
			
		||||
	visited := aoc.NewSet([]int{}...)
 | 
			
		||||
	visited := aoc.Set([]int{}...)
 | 
			
		||||
	dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
 | 
			
		||||
 | 
			
		||||
	dist.Set(0, 0)
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,6 @@ import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	_ "embed"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"slices"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	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 {
 | 
			
		||||
						counts[v]++
 | 
			
		||||
						return counts
 | 
			
		||||
					}, [3]int{}, slices.Values(maps.Values(memo)))
 | 
			
		||||
					}, [3]int{}, maps.Values(memo)...)
 | 
			
		||||
 | 
			
		||||
				// fmt.Println(i, counts)
 | 
			
		||||
				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 {
 | 
			
		||||
			sum += hash(t)
 | 
			
		||||
			return sum
 | 
			
		||||
		}, 0, slices.Values(ops))
 | 
			
		||||
		}, 0, ops...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var boxen boxes
 | 
			
		||||
 | 
			
		||||
	boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
 | 
			
		||||
		return b.Op(op)
 | 
			
		||||
	}, boxen, slices.Values(ops))
 | 
			
		||||
	}, boxen, ops...)
 | 
			
		||||
 | 
			
		||||
	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