Compare commits
56 Commits
724fb14ff2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| b495e01ab4 | |||
| aa84e3974b | |||
|
aa0a2b7b7d
|
|||
|
77a0669f45
|
|||
|
c077b91c41
|
|||
| b3c36c1af1 | |||
|
6a17669107
|
|||
|
127257c494
|
|||
|
7b9a71f84c
|
|||
|
669e2cfb2c
|
|||
|
2274eca981
|
|||
|
b1e4c4d634
|
|||
|
4b3fc7eb73
|
|||
|
0d652660f1
|
|||
|
e046a6c06d
|
|||
|
04bbac8559
|
|||
|
3c9af95ec4
|
|||
|
50af2114d4
|
|||
|
f8fa61672f
|
|||
|
951c2c298a
|
|||
|
328a0f3eb3
|
|||
|
7d7402f054
|
|||
|
7585526634
|
|||
|
924c8d74f3
|
|||
|
22184ed9c7
|
|||
| 74a952e82b | |||
| 62f8338227 | |||
| 39c6f8ed4d | |||
|
2c959c109b
|
|||
|
eb1eaaab43
|
|||
|
adc01f4df9
|
|||
|
fd85530d88
|
|||
|
0d78959bea
|
|||
|
86f2f7a6f2
|
|||
| 378e403c1c | |||
| 06a22511b5 | |||
|
a2563b9d31
|
|||
| 3c2ea4ed9e | |||
|
1fac5f7b4d
|
|||
| 1a3374a557 | |||
| 170fecc9f6 | |||
| 58e482b125 | |||
|
7847d11f95
|
|||
| d21005c534 | |||
| 3e0ed68db3 | |||
|
f1ac3ea35f
|
|||
| f0696a6fe6 | |||
|
786a5bae35
|
|||
| e82c9a97c4 | |||
| b2da6a35e7 | |||
|
970f5b2d76
|
|||
| 8e451050b1 | |||
|
761013df81
|
|||
|
eb9e770a94
|
|||
|
13888edaff
|
|||
|
50f1016372
|
@@ -28,6 +28,6 @@ jobs:
|
|||||||
go-version: 1.21.3
|
go-version: 1.21.3
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: go test --race -cover ./...
|
run: go test -timeout 240s -race -cover ./...
|
||||||
|
|
||||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||||
|
|||||||
6
README.md.sig
Normal file
6
README.md.sig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN SSH SIGNATURE-----
|
||||||
|
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgZ+OuJYdd3UiUbyBuO1RlsQR20a
|
||||||
|
Qm5mKneuMxRjGo3zkAAAAEZmlsZQAAAAAAAAAGc2hhNTEyAAAAUwAAAAtzc2gtZWQyNTUx
|
||||||
|
OQAAAED8T4C6WILXYZ1KxqDIlVhlrAEjr1Vc+tn8ypcVM3bN7iOexVvuUuvm90nr8eEwKU
|
||||||
|
acrdDxmq2S+oysQbK+pMUE
|
||||||
|
-----END SSH SIGNATURE-----
|
||||||
@@ -30,7 +30,6 @@ func TestExample1(t *testing.T) {
|
|||||||
is.Equal(result.sum, 142)
|
is.Equal(result.sum, 142)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func TestExample2(t *testing.T) {
|
func TestExample2(t *testing.T) {
|
||||||
is := is.New(t)
|
is := is.New(t)
|
||||||
scan := bufio.NewScanner(bytes.NewReader(example2))
|
scan := bufio.NewScanner(bytes.NewReader(example2))
|
||||||
1000
aoc2023/day07/input2.txt
Normal file
1000
aoc2023/day07/input2.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
aoc "go.sour.is/advent-of-code"
|
aoc "go.sour.is/advent-of-code"
|
||||||
@@ -62,7 +63,7 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||||||
func(i int, v int, counts [3]int) [3]int {
|
func(i int, v int, counts [3]int) [3]int {
|
||||||
counts[v]++
|
counts[v]++
|
||||||
return counts
|
return counts
|
||||||
}, [3]int{}, maps.Values(memo)...)
|
}, [3]int{}, slices.Values(maps.Values(memo)))
|
||||||
|
|
||||||
// fmt.Println(i, counts)
|
// fmt.Println(i, counts)
|
||||||
i = 1_000_000_000 - (1_000_000_000-counts[0]-counts[1])%counts[2]
|
i = 1_000_000_000 - (1_000_000_000-counts[0]-counts[1])%counts[2]
|
||||||
@@ -36,11 +36,10 @@ func TestSolution(t *testing.T) {
|
|||||||
is.NoErr(err)
|
is.NoErr(err)
|
||||||
|
|
||||||
t.Log(result)
|
t.Log(result)
|
||||||
is.True(result.valuePT2 < 87286) // first submission
|
is.True(result.valuePT2 < 87286) // first submission
|
||||||
is.True(result.valuePT2 < 87292) // second submission
|
is.True(result.valuePT2 < 87292) // second submission
|
||||||
is.True(result.valuePT2 < 87287) // third submission
|
is.True(result.valuePT2 < 87287) // third submission
|
||||||
|
|
||||||
is.Equal(result.valuePT1, 110407)
|
is.Equal(result.valuePT1, 110407)
|
||||||
is.Equal(result.valuePT2, 87273)
|
is.Equal(result.valuePT2, 87273)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,14 +32,14 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||||||
r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int {
|
r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int {
|
||||||
sum += hash(t)
|
sum += hash(t)
|
||||||
return sum
|
return sum
|
||||||
}, 0, ops...)
|
}, 0, slices.Values(ops))
|
||||||
}
|
}
|
||||||
|
|
||||||
var boxen boxes
|
var boxen boxes
|
||||||
|
|
||||||
boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
|
boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
|
||||||
return b.Op(op)
|
return b.Op(op)
|
||||||
}, boxen, ops...)
|
}, boxen, slices.Values(ops))
|
||||||
|
|
||||||
r.valuePT2 = boxen.Sum()
|
r.valuePT2 = boxen.Sum()
|
||||||
|
|
||||||
@@ -32,15 +32,15 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||||||
|
|
||||||
options := make([]int, 2*(rows+cols)+2)
|
options := make([]int, 2*(rows+cols)+2)
|
||||||
i := 0
|
i := 0
|
||||||
for j:=0; j<=rows-1; j++ {
|
for j := 0; j <= rows-1; j++ {
|
||||||
options[i+0] = runCycle(m, ray{[2]int{j, -1}, RT})
|
options[i+0] = runCycle(m, ray{[2]int{j, -1}, RT})
|
||||||
options[i+1] = runCycle(m, ray{[2]int{j, cols}, LF})
|
options[i+1] = runCycle(m, ray{[2]int{j, cols}, LF})
|
||||||
i+=2
|
i += 2
|
||||||
}
|
}
|
||||||
for j:=0; j<=cols-1; j++ {
|
for j := 0; j <= cols-1; j++ {
|
||||||
options[i+0] = runCycle(m, ray{[2]int{-1, j}, DN})
|
options[i+0] = runCycle(m, ray{[2]int{-1, j}, DN})
|
||||||
options[i+1] = runCycle(m, ray{[2]int{rows, j}, UP})
|
options[i+1] = runCycle(m, ray{[2]int{rows, j}, UP})
|
||||||
i+=2
|
i += 2
|
||||||
}
|
}
|
||||||
|
|
||||||
// fmt.Println(options)
|
// fmt.Println(options)
|
||||||
@@ -96,7 +96,6 @@ func (m *Map) Get(p [2]int) rune {
|
|||||||
return (*m)[p[0]][p[1]]
|
return (*m)[p[0]][p[1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func runCycle(m Map, r ray) int {
|
func runCycle(m Map, r ray) int {
|
||||||
current := r
|
current := r
|
||||||
|
|
||||||
225
aoc2023/day17/main.go
Normal file
225
aoc2023/day17/main.go
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
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 m aoc.Map[int16, rune]
|
||||||
|
|
||||||
|
for scan.Scan() {
|
||||||
|
text := scan.Text()
|
||||||
|
m = append(m, []rune(text))
|
||||||
|
}
|
||||||
|
log("start day 17")
|
||||||
|
|
||||||
|
result := result{}
|
||||||
|
result.valuePT1 = search(m, 1, 3, seenFn)
|
||||||
|
log("result from part 1 = ", result.valuePT1)
|
||||||
|
|
||||||
|
result.valuePT2 = search(m, 4, 10, nil)
|
||||||
|
log("result from part 2 = ", result.valuePT2)
|
||||||
|
|
||||||
|
return &result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Point = aoc.Point[int16]
|
||||||
|
type Map = aoc.Map[int16, rune]
|
||||||
|
|
||||||
|
// rotate for changing direction
|
||||||
|
type rotate int8
|
||||||
|
|
||||||
|
const (
|
||||||
|
CW rotate = 1
|
||||||
|
CCW rotate = -1
|
||||||
|
)
|
||||||
|
|
||||||
|
// diretion of path steps
|
||||||
|
type direction int8
|
||||||
|
|
||||||
|
var (
|
||||||
|
U = Point{-1, 0}
|
||||||
|
R = Point{0, 1}
|
||||||
|
D = Point{1, 0}
|
||||||
|
L = Point{0, -1}
|
||||||
|
)
|
||||||
|
|
||||||
|
var directions = []Point{U, R, D, L}
|
||||||
|
|
||||||
|
var directionIDX = func() map[Point]direction {
|
||||||
|
m := make(map[Point]direction, len(directions))
|
||||||
|
for k, v := range directions {
|
||||||
|
m[v] = direction(k)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}()
|
||||||
|
|
||||||
|
// position on the map
|
||||||
|
type position struct {
|
||||||
|
loc Point
|
||||||
|
direction Point
|
||||||
|
steps int8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p position) step() position {
|
||||||
|
return position{p.loc.Add(p.direction), p.direction, p.steps + 1}
|
||||||
|
}
|
||||||
|
func (p position) rotateAndStep(towards rotate) position {
|
||||||
|
d := directions[(int8(directionIDX[p.direction])+int8(towards)+4)%4]
|
||||||
|
return position{p.loc.Add(d), d, 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
// implements FindPath graph interface
|
||||||
|
type graph struct {
|
||||||
|
min, max int8
|
||||||
|
m Map
|
||||||
|
target Point
|
||||||
|
reads int
|
||||||
|
seenFn func(a position) position
|
||||||
|
}
|
||||||
|
|
||||||
|
// Neighbors returns valid steps from given position. if at target returns none.
|
||||||
|
func (g *graph) Neighbors(current position) []position {
|
||||||
|
var nbs []position
|
||||||
|
|
||||||
|
if current.steps == 0 {
|
||||||
|
return []position{
|
||||||
|
{R, R, 1},
|
||||||
|
{D, D, 1},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if current.loc == g.target {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if left := current.rotateAndStep(CCW); current.steps >= g.min && g.m.Valid(left.loc) {
|
||||||
|
nbs = append(nbs, left)
|
||||||
|
}
|
||||||
|
|
||||||
|
if right := current.rotateAndStep(CW); current.steps >= g.min && g.m.Valid(right.loc) {
|
||||||
|
nbs = append(nbs, right)
|
||||||
|
}
|
||||||
|
|
||||||
|
if forward := current.step(); current.steps < g.max && g.m.Valid(forward.loc) {
|
||||||
|
nbs = append(nbs, forward)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nbs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cost calculates heat cost to neighbor from map
|
||||||
|
func (g *graph) Cost(a, b position) int16 {
|
||||||
|
g.reads++
|
||||||
|
_, r, _ := g.m.Get(b.loc)
|
||||||
|
return int16(r - '0')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Potential calculates distance to target
|
||||||
|
// func (g *graph) Potential(a position) int16 {
|
||||||
|
// return aoc.ManhattanDistance(a.loc, g.target)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Target returns true when target reached. receives node and cost.
|
||||||
|
func (g *graph) Target(a position, c int16) bool {
|
||||||
|
if a.loc == g.target && a.steps >= g.min && a.steps <= g.max {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seen attempt at simplifying the seen to use horizontal/vertical and no steps.
|
||||||
|
// It returns correct for part1 but not part 2..
|
||||||
|
func (g *graph) Seen(a position) position {
|
||||||
|
if g.seenFn != nil {
|
||||||
|
return g.seenFn(a)
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func seenFn(a position) position {
|
||||||
|
if a.direction == U {
|
||||||
|
a.direction = D
|
||||||
|
}
|
||||||
|
if a.direction == L {
|
||||||
|
a.direction = R
|
||||||
|
}
|
||||||
|
// a.steps = 0
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func search(m Map, minSteps, maxSteps int8, seenFn func(position) position) int {
|
||||||
|
rows, cols := m.Size()
|
||||||
|
start := Point{}
|
||||||
|
target := Point{rows - 1, cols - 1}
|
||||||
|
|
||||||
|
g := graph{min: minSteps, max: maxSteps, m: m, target: target, seenFn: seenFn}
|
||||||
|
|
||||||
|
cost, path, closed := aoc.FindPath[int16, position](&g, position{loc: start}, position{loc: target})
|
||||||
|
|
||||||
|
log("total map reads = ", g.reads, "cost = ", cost)
|
||||||
|
printGraph(m, path, closed, g.seenFn)
|
||||||
|
|
||||||
|
return int(cost)
|
||||||
|
}
|
||||||
|
|
||||||
|
// printGraph with the path/cost overlay
|
||||||
|
func printGraph(m Map, path []position, closed map[position]int16, seenFn func(a position) position) {
|
||||||
|
pts := make(map[Point]position, len(path))
|
||||||
|
for _, pt := range path {
|
||||||
|
pts[pt.loc] = pt
|
||||||
|
}
|
||||||
|
|
||||||
|
clpt := make(map[position]position, len(closed))
|
||||||
|
for pt := range closed {
|
||||||
|
clpt[position{loc: pt.loc, steps: pt.steps}] = pt
|
||||||
|
}
|
||||||
|
|
||||||
|
for r, row := range m {
|
||||||
|
// if r == 0 {
|
||||||
|
// for c := range row {
|
||||||
|
// if c == 0 {
|
||||||
|
// fmt.Print(" ")
|
||||||
|
// }
|
||||||
|
// fmt.Printf("% 5d", c)
|
||||||
|
// }
|
||||||
|
// fmt.Println("")
|
||||||
|
// }
|
||||||
|
for c := range row {
|
||||||
|
// if c == 0 {
|
||||||
|
// fmt.Printf("% 5d", r)
|
||||||
|
// }
|
||||||
|
|
||||||
|
if pt, ok := pts[Point{int16(r), int16(c)}]; ok {
|
||||||
|
if seenFn != nil {
|
||||||
|
pt = seenFn(pt)
|
||||||
|
}
|
||||||
|
_ = pt
|
||||||
|
// fmt.Printf("% 5d", closed[pt])
|
||||||
|
fmt.Print("*")
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt.Print(" ....")
|
||||||
|
fmt.Print(" ")
|
||||||
|
}
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
41
aoc2023/day17/main_test.go
Normal file
41
aoc2023/day17/main_test.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
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, 102)
|
||||||
|
is.Equal(result.valuePT2, 94)
|
||||||
|
}
|
||||||
|
|
||||||
|
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, 843)
|
||||||
|
is.Equal(result.valuePT2, 1017)
|
||||||
|
}
|
||||||
14
aoc2023/day18/example.txt
Normal file
14
aoc2023/day18/example.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
R 6 (#70c710)
|
||||||
|
D 5 (#0dc571)
|
||||||
|
L 2 (#5713f0)
|
||||||
|
D 2 (#d2c081)
|
||||||
|
R 2 (#59c680)
|
||||||
|
D 2 (#411b91)
|
||||||
|
L 5 (#8ceee2)
|
||||||
|
U 2 (#caa173)
|
||||||
|
L 1 (#1b58a2)
|
||||||
|
U 2 (#caa171)
|
||||||
|
R 2 (#7807d2)
|
||||||
|
U 3 (#a77fa3)
|
||||||
|
L 2 (#015232)
|
||||||
|
U 2 (#7a21e3)
|
||||||
766
aoc2023/day18/input.txt
Normal file
766
aoc2023/day18/input.txt
Normal file
@@ -0,0 +1,766 @@
|
|||||||
|
R 4 (#0a7a60)
|
||||||
|
U 8 (#4453b3)
|
||||||
|
R 6 (#8e4f70)
|
||||||
|
U 2 (#4453b1)
|
||||||
|
R 4 (#0feb00)
|
||||||
|
U 4 (#355591)
|
||||||
|
R 8 (#2a09c0)
|
||||||
|
U 4 (#544c71)
|
||||||
|
R 4 (#472930)
|
||||||
|
U 2 (#199e33)
|
||||||
|
R 3 (#3d8df0)
|
||||||
|
U 5 (#199e31)
|
||||||
|
R 7 (#45de50)
|
||||||
|
U 4 (#57a941)
|
||||||
|
L 7 (#671c70)
|
||||||
|
U 5 (#5e5e81)
|
||||||
|
R 4 (#2e9b60)
|
||||||
|
U 8 (#490881)
|
||||||
|
L 7 (#1846f0)
|
||||||
|
U 3 (#304101)
|
||||||
|
L 4 (#1846f2)
|
||||||
|
D 2 (#58f3f1)
|
||||||
|
L 9 (#2e9b62)
|
||||||
|
D 2 (#56dcd1)
|
||||||
|
L 2 (#671c72)
|
||||||
|
D 9 (#275fd1)
|
||||||
|
L 4 (#76b7b2)
|
||||||
|
U 9 (#5b9641)
|
||||||
|
L 4 (#1d3212)
|
||||||
|
U 10 (#3d1841)
|
||||||
|
L 3 (#5ad5e2)
|
||||||
|
D 6 (#010211)
|
||||||
|
L 5 (#13ec52)
|
||||||
|
D 8 (#166471)
|
||||||
|
L 3 (#53ebc0)
|
||||||
|
D 5 (#0fdba1)
|
||||||
|
L 4 (#54e450)
|
||||||
|
D 9 (#440a21)
|
||||||
|
L 3 (#49b242)
|
||||||
|
D 5 (#2f0171)
|
||||||
|
L 6 (#447332)
|
||||||
|
D 4 (#182561)
|
||||||
|
L 8 (#1aaaa2)
|
||||||
|
D 6 (#0996a1)
|
||||||
|
L 4 (#1c1212)
|
||||||
|
D 6 (#5780d1)
|
||||||
|
L 7 (#0fc1d2)
|
||||||
|
D 7 (#36cb41)
|
||||||
|
L 3 (#505552)
|
||||||
|
D 7 (#8d8b81)
|
||||||
|
R 4 (#2bf742)
|
||||||
|
D 7 (#152791)
|
||||||
|
R 5 (#760492)
|
||||||
|
D 3 (#11a991)
|
||||||
|
R 3 (#5debc0)
|
||||||
|
D 10 (#59f211)
|
||||||
|
L 4 (#66d342)
|
||||||
|
D 8 (#1fc6b1)
|
||||||
|
R 4 (#66d340)
|
||||||
|
D 6 (#72dff1)
|
||||||
|
L 2 (#3f1b10)
|
||||||
|
D 4 (#2fca13)
|
||||||
|
L 10 (#2d0162)
|
||||||
|
D 5 (#8b5e53)
|
||||||
|
L 6 (#2d0160)
|
||||||
|
U 2 (#317053)
|
||||||
|
L 2 (#650c20)
|
||||||
|
U 7 (#2bed01)
|
||||||
|
R 10 (#409ed0)
|
||||||
|
U 2 (#166713)
|
||||||
|
L 10 (#939350)
|
||||||
|
U 6 (#166711)
|
||||||
|
L 4 (#38a180)
|
||||||
|
D 3 (#1d95f1)
|
||||||
|
L 6 (#11ea60)
|
||||||
|
D 5 (#931dc1)
|
||||||
|
R 6 (#11bf70)
|
||||||
|
D 7 (#536051)
|
||||||
|
L 3 (#995b60)
|
||||||
|
D 2 (#254e91)
|
||||||
|
L 3 (#332fd2)
|
||||||
|
U 6 (#7669f1)
|
||||||
|
L 3 (#574642)
|
||||||
|
U 6 (#1778a1)
|
||||||
|
L 3 (#1a00c2)
|
||||||
|
U 5 (#2eaa81)
|
||||||
|
L 3 (#1cf8e2)
|
||||||
|
U 6 (#0c71a1)
|
||||||
|
L 6 (#868472)
|
||||||
|
U 3 (#0a9fd1)
|
||||||
|
R 9 (#104c02)
|
||||||
|
U 4 (#082451)
|
||||||
|
L 7 (#850d02)
|
||||||
|
U 6 (#082453)
|
||||||
|
L 7 (#322552)
|
||||||
|
U 3 (#1339d1)
|
||||||
|
L 6 (#8e11d2)
|
||||||
|
U 4 (#6c5691)
|
||||||
|
R 6 (#1dda10)
|
||||||
|
U 3 (#25e5c3)
|
||||||
|
R 7 (#370670)
|
||||||
|
U 4 (#9324f1)
|
||||||
|
L 3 (#451030)
|
||||||
|
U 7 (#1f1021)
|
||||||
|
L 7 (#0ba3c0)
|
||||||
|
U 5 (#8a10a3)
|
||||||
|
L 8 (#67db30)
|
||||||
|
U 5 (#282473)
|
||||||
|
L 4 (#0cd350)
|
||||||
|
U 4 (#25e5c1)
|
||||||
|
R 3 (#6b4ee0)
|
||||||
|
U 4 (#333cf1)
|
||||||
|
R 5 (#02b610)
|
||||||
|
D 4 (#4e7cc1)
|
||||||
|
R 3 (#92abb0)
|
||||||
|
U 5 (#2f6ff1)
|
||||||
|
R 5 (#483360)
|
||||||
|
U 5 (#7b1cd1)
|
||||||
|
L 8 (#3a5d50)
|
||||||
|
U 3 (#1d2461)
|
||||||
|
R 8 (#3b2fd0)
|
||||||
|
U 5 (#630763)
|
||||||
|
R 6 (#5033c0)
|
||||||
|
U 3 (#252523)
|
||||||
|
R 7 (#08eeb0)
|
||||||
|
U 8 (#516633)
|
||||||
|
L 7 (#156240)
|
||||||
|
U 4 (#2db063)
|
||||||
|
L 3 (#791070)
|
||||||
|
D 5 (#2920a3)
|
||||||
|
L 3 (#0dafe0)
|
||||||
|
U 5 (#4185b3)
|
||||||
|
L 5 (#7ac0e0)
|
||||||
|
U 2 (#5a6cd3)
|
||||||
|
L 2 (#3ca790)
|
||||||
|
U 7 (#755403)
|
||||||
|
L 4 (#3b0740)
|
||||||
|
U 5 (#2004a3)
|
||||||
|
L 3 (#2db4f0)
|
||||||
|
U 6 (#602a23)
|
||||||
|
R 5 (#32c1c0)
|
||||||
|
D 2 (#000f53)
|
||||||
|
R 5 (#388360)
|
||||||
|
D 7 (#24d9e3)
|
||||||
|
R 4 (#4703a0)
|
||||||
|
D 3 (#2f1133)
|
||||||
|
R 3 (#4703a2)
|
||||||
|
U 11 (#52e853)
|
||||||
|
R 5 (#278132)
|
||||||
|
D 11 (#0665e3)
|
||||||
|
R 3 (#239112)
|
||||||
|
U 6 (#8f0ad1)
|
||||||
|
R 5 (#447de2)
|
||||||
|
U 6 (#8f0ad3)
|
||||||
|
R 6 (#636122)
|
||||||
|
U 2 (#187283)
|
||||||
|
R 3 (#5aae62)
|
||||||
|
U 10 (#1d8833)
|
||||||
|
L 5 (#476db0)
|
||||||
|
U 5 (#136393)
|
||||||
|
L 7 (#29e6b0)
|
||||||
|
U 5 (#136391)
|
||||||
|
R 7 (#3ba060)
|
||||||
|
U 3 (#635e23)
|
||||||
|
L 5 (#2042f0)
|
||||||
|
U 3 (#181643)
|
||||||
|
L 6 (#5af952)
|
||||||
|
U 8 (#28d0b1)
|
||||||
|
L 2 (#4a98f2)
|
||||||
|
U 9 (#28d0b3)
|
||||||
|
L 6 (#27a572)
|
||||||
|
D 3 (#3d7213)
|
||||||
|
L 4 (#516842)
|
||||||
|
D 11 (#21ef63)
|
||||||
|
L 5 (#38e342)
|
||||||
|
D 2 (#1118b3)
|
||||||
|
L 3 (#560502)
|
||||||
|
D 9 (#1118b1)
|
||||||
|
R 2 (#1c39a2)
|
||||||
|
D 2 (#303ab3)
|
||||||
|
R 6 (#716ba0)
|
||||||
|
D 6 (#780a93)
|
||||||
|
L 8 (#77ec30)
|
||||||
|
U 2 (#780a91)
|
||||||
|
L 3 (#271100)
|
||||||
|
U 10 (#5882f3)
|
||||||
|
L 4 (#2050c2)
|
||||||
|
D 3 (#434843)
|
||||||
|
L 3 (#7d9572)
|
||||||
|
D 2 (#3129b3)
|
||||||
|
L 5 (#21fb12)
|
||||||
|
D 5 (#8c2c33)
|
||||||
|
L 4 (#57bf92)
|
||||||
|
D 6 (#2730b3)
|
||||||
|
L 4 (#6a3902)
|
||||||
|
D 8 (#4656a3)
|
||||||
|
L 5 (#60ac80)
|
||||||
|
D 4 (#43b863)
|
||||||
|
R 9 (#3d69a0)
|
||||||
|
D 8 (#3ca913)
|
||||||
|
L 2 (#411d80)
|
||||||
|
D 3 (#725383)
|
||||||
|
L 8 (#4a98d0)
|
||||||
|
D 9 (#274553)
|
||||||
|
L 5 (#580d60)
|
||||||
|
U 5 (#568223)
|
||||||
|
L 6 (#473af0)
|
||||||
|
U 5 (#827593)
|
||||||
|
L 7 (#251dc2)
|
||||||
|
U 5 (#0fcea3)
|
||||||
|
L 8 (#5ae3d2)
|
||||||
|
U 3 (#4efa11)
|
||||||
|
R 9 (#389852)
|
||||||
|
U 2 (#7f7f91)
|
||||||
|
R 6 (#618342)
|
||||||
|
U 3 (#441143)
|
||||||
|
L 7 (#886df2)
|
||||||
|
U 3 (#26a093)
|
||||||
|
L 8 (#886df0)
|
||||||
|
U 4 (#63c7d3)
|
||||||
|
L 3 (#04f842)
|
||||||
|
D 10 (#0fcea1)
|
||||||
|
L 6 (#388e62)
|
||||||
|
U 10 (#3ae7f3)
|
||||||
|
L 3 (#2a6880)
|
||||||
|
U 6 (#3bfd53)
|
||||||
|
L 6 (#73a0c0)
|
||||||
|
U 5 (#3bfd51)
|
||||||
|
L 4 (#0d18a0)
|
||||||
|
U 2 (#19da93)
|
||||||
|
L 6 (#120600)
|
||||||
|
U 8 (#233b53)
|
||||||
|
L 6 (#2e1050)
|
||||||
|
U 3 (#4b2aa3)
|
||||||
|
L 4 (#5f9930)
|
||||||
|
U 10 (#6e65f1)
|
||||||
|
R 6 (#1eefa0)
|
||||||
|
U 9 (#50b9d3)
|
||||||
|
R 2 (#548ed0)
|
||||||
|
U 9 (#50b9d1)
|
||||||
|
R 7 (#8bd9f0)
|
||||||
|
U 4 (#5ae473)
|
||||||
|
R 6 (#0b0490)
|
||||||
|
U 10 (#186891)
|
||||||
|
R 4 (#764830)
|
||||||
|
U 7 (#33b0e1)
|
||||||
|
R 5 (#363c90)
|
||||||
|
U 8 (#7bd631)
|
||||||
|
R 7 (#031e30)
|
||||||
|
U 7 (#095881)
|
||||||
|
R 3 (#640e50)
|
||||||
|
D 5 (#02e7f3)
|
||||||
|
R 7 (#0922f0)
|
||||||
|
D 7 (#6b7af3)
|
||||||
|
R 9 (#0922f2)
|
||||||
|
D 3 (#62e543)
|
||||||
|
R 3 (#21e320)
|
||||||
|
U 9 (#5ead81)
|
||||||
|
R 7 (#01fd70)
|
||||||
|
D 9 (#3b0cf1)
|
||||||
|
R 2 (#2758a0)
|
||||||
|
D 5 (#7279b1)
|
||||||
|
R 8 (#5c7dc0)
|
||||||
|
D 7 (#3c8db1)
|
||||||
|
R 4 (#3c3740)
|
||||||
|
U 2 (#26b151)
|
||||||
|
R 6 (#11eb12)
|
||||||
|
U 4 (#587921)
|
||||||
|
R 6 (#11eb10)
|
||||||
|
U 4 (#320051)
|
||||||
|
R 4 (#038630)
|
||||||
|
U 3 (#6a2e61)
|
||||||
|
R 2 (#4ff680)
|
||||||
|
U 5 (#3c57f1)
|
||||||
|
R 9 (#0b2440)
|
||||||
|
U 8 (#497533)
|
||||||
|
L 6 (#704680)
|
||||||
|
U 11 (#549113)
|
||||||
|
R 6 (#23b470)
|
||||||
|
U 4 (#9e0641)
|
||||||
|
R 7 (#1aeec0)
|
||||||
|
D 7 (#4a6331)
|
||||||
|
R 2 (#547d80)
|
||||||
|
D 5 (#457a71)
|
||||||
|
R 9 (#7daa90)
|
||||||
|
D 4 (#16d7b1)
|
||||||
|
L 6 (#266810)
|
||||||
|
D 3 (#363561)
|
||||||
|
L 5 (#5312b2)
|
||||||
|
D 4 (#42c301)
|
||||||
|
R 5 (#9a0952)
|
||||||
|
D 7 (#42c303)
|
||||||
|
R 7 (#7d1df2)
|
||||||
|
D 4 (#51e321)
|
||||||
|
R 5 (#609422)
|
||||||
|
D 4 (#3b8f01)
|
||||||
|
R 6 (#644792)
|
||||||
|
U 4 (#2d8b11)
|
||||||
|
R 7 (#22bbc2)
|
||||||
|
D 7 (#6b39b1)
|
||||||
|
R 5 (#680e72)
|
||||||
|
U 2 (#7f9f31)
|
||||||
|
R 3 (#0e9b52)
|
||||||
|
U 3 (#3086c1)
|
||||||
|
R 3 (#5a60c0)
|
||||||
|
U 6 (#53b6e3)
|
||||||
|
R 7 (#8117d0)
|
||||||
|
U 7 (#53b6e1)
|
||||||
|
R 3 (#2cb930)
|
||||||
|
U 3 (#1bffd1)
|
||||||
|
R 6 (#4539f0)
|
||||||
|
U 8 (#680411)
|
||||||
|
R 4 (#6032c0)
|
||||||
|
U 6 (#255061)
|
||||||
|
R 3 (#5562a0)
|
||||||
|
U 6 (#088071)
|
||||||
|
R 3 (#3bf2f0)
|
||||||
|
U 5 (#52bdb1)
|
||||||
|
L 6 (#070500)
|
||||||
|
U 5 (#69e001)
|
||||||
|
R 6 (#070502)
|
||||||
|
U 3 (#071051)
|
||||||
|
R 2 (#036000)
|
||||||
|
U 4 (#0ea8a1)
|
||||||
|
R 5 (#05e4d0)
|
||||||
|
U 3 (#674de1)
|
||||||
|
R 3 (#804250)
|
||||||
|
D 6 (#3ffca1)
|
||||||
|
R 4 (#23dcb2)
|
||||||
|
D 6 (#9f9841)
|
||||||
|
L 5 (#45f210)
|
||||||
|
D 9 (#15efc1)
|
||||||
|
R 5 (#45f212)
|
||||||
|
D 4 (#969551)
|
||||||
|
L 9 (#23dcb0)
|
||||||
|
D 2 (#41bea1)
|
||||||
|
L 4 (#2f2a32)
|
||||||
|
D 4 (#71ffd1)
|
||||||
|
R 3 (#5c0bb2)
|
||||||
|
D 7 (#6f3501)
|
||||||
|
R 4 (#2b0a72)
|
||||||
|
D 4 (#7b3571)
|
||||||
|
R 3 (#1c67d2)
|
||||||
|
U 11 (#42f011)
|
||||||
|
R 3 (#51ae62)
|
||||||
|
D 3 (#75fcf1)
|
||||||
|
R 3 (#1f4742)
|
||||||
|
D 4 (#2813f1)
|
||||||
|
R 4 (#3d1812)
|
||||||
|
D 2 (#2b1d01)
|
||||||
|
R 11 (#1eb302)
|
||||||
|
U 3 (#27b0a1)
|
||||||
|
R 4 (#227b20)
|
||||||
|
U 5 (#34b7e1)
|
||||||
|
R 10 (#201220)
|
||||||
|
U 7 (#0502f3)
|
||||||
|
R 4 (#5ab7f0)
|
||||||
|
U 4 (#0502f1)
|
||||||
|
R 4 (#5d09b0)
|
||||||
|
U 7 (#504a81)
|
||||||
|
R 7 (#1e8250)
|
||||||
|
U 3 (#715aa1)
|
||||||
|
R 6 (#26d290)
|
||||||
|
U 6 (#9a12f1)
|
||||||
|
L 3 (#18be90)
|
||||||
|
U 8 (#037d11)
|
||||||
|
L 5 (#647600)
|
||||||
|
U 3 (#40b983)
|
||||||
|
L 5 (#04e450)
|
||||||
|
U 3 (#9a9a43)
|
||||||
|
L 8 (#04e452)
|
||||||
|
U 6 (#8af153)
|
||||||
|
R 8 (#6cbc90)
|
||||||
|
U 4 (#04d121)
|
||||||
|
L 4 (#285292)
|
||||||
|
U 3 (#688d51)
|
||||||
|
L 6 (#176332)
|
||||||
|
U 4 (#400a91)
|
||||||
|
L 5 (#176330)
|
||||||
|
U 5 (#43def1)
|
||||||
|
R 2 (#285290)
|
||||||
|
U 2 (#3e0711)
|
||||||
|
R 3 (#7eb9c0)
|
||||||
|
U 7 (#36f611)
|
||||||
|
R 7 (#666af0)
|
||||||
|
D 7 (#381b31)
|
||||||
|
R 3 (#298922)
|
||||||
|
U 3 (#475671)
|
||||||
|
R 6 (#977c12)
|
||||||
|
D 4 (#602d01)
|
||||||
|
R 6 (#25b0c2)
|
||||||
|
D 6 (#7ede81)
|
||||||
|
R 3 (#1d58c2)
|
||||||
|
D 8 (#873523)
|
||||||
|
L 9 (#265ae2)
|
||||||
|
D 3 (#57d663)
|
||||||
|
R 7 (#1565c2)
|
||||||
|
D 8 (#06ed11)
|
||||||
|
R 4 (#a348c2)
|
||||||
|
D 2 (#06ed13)
|
||||||
|
R 8 (#12d052)
|
||||||
|
D 4 (#2d3741)
|
||||||
|
L 7 (#0ccfd2)
|
||||||
|
D 3 (#1fcd61)
|
||||||
|
R 4 (#39a4c2)
|
||||||
|
D 3 (#44f7f1)
|
||||||
|
R 6 (#5c3202)
|
||||||
|
D 8 (#2625c1)
|
||||||
|
L 8 (#2b08c2)
|
||||||
|
D 2 (#20d7e1)
|
||||||
|
L 2 (#67b892)
|
||||||
|
D 10 (#546471)
|
||||||
|
R 7 (#484ef2)
|
||||||
|
D 7 (#49bc91)
|
||||||
|
R 4 (#91aa72)
|
||||||
|
U 11 (#499591)
|
||||||
|
R 3 (#0048b2)
|
||||||
|
U 7 (#34a7a1)
|
||||||
|
R 7 (#514600)
|
||||||
|
U 8 (#1cdc43)
|
||||||
|
L 7 (#471470)
|
||||||
|
U 3 (#8c8393)
|
||||||
|
R 3 (#18a780)
|
||||||
|
U 5 (#8c8391)
|
||||||
|
R 3 (#4e6f80)
|
||||||
|
U 3 (#1cdc41)
|
||||||
|
R 8 (#428930)
|
||||||
|
U 5 (#5dcb51)
|
||||||
|
R 3 (#4b21e2)
|
||||||
|
U 4 (#0464b1)
|
||||||
|
R 9 (#850552)
|
||||||
|
D 8 (#464881)
|
||||||
|
R 7 (#543852)
|
||||||
|
D 3 (#2d3a11)
|
||||||
|
R 3 (#081b22)
|
||||||
|
D 5 (#0cc731)
|
||||||
|
R 7 (#6990e0)
|
||||||
|
D 3 (#79d7b1)
|
||||||
|
R 3 (#509520)
|
||||||
|
D 5 (#438571)
|
||||||
|
R 3 (#27d510)
|
||||||
|
D 3 (#30d2d3)
|
||||||
|
L 8 (#1b7a00)
|
||||||
|
D 5 (#8a0da3)
|
||||||
|
L 8 (#1b7a02)
|
||||||
|
U 5 (#027cb3)
|
||||||
|
L 7 (#350130)
|
||||||
|
D 8 (#2ff771)
|
||||||
|
R 7 (#16dc02)
|
||||||
|
D 2 (#68f1c1)
|
||||||
|
R 5 (#02f782)
|
||||||
|
D 6 (#4e2a41)
|
||||||
|
R 11 (#448e32)
|
||||||
|
D 5 (#2cfac1)
|
||||||
|
L 11 (#417502)
|
||||||
|
D 5 (#2cfac3)
|
||||||
|
L 4 (#22f022)
|
||||||
|
U 9 (#1e9f01)
|
||||||
|
L 5 (#543572)
|
||||||
|
U 3 (#076e31)
|
||||||
|
L 6 (#081b20)
|
||||||
|
U 5 (#1ae851)
|
||||||
|
L 3 (#823132)
|
||||||
|
U 9 (#2d7993)
|
||||||
|
L 4 (#5738f2)
|
||||||
|
D 8 (#79e273)
|
||||||
|
L 4 (#5c9ad2)
|
||||||
|
D 8 (#4ed1b3)
|
||||||
|
L 3 (#311722)
|
||||||
|
D 4 (#0d5493)
|
||||||
|
L 6 (#5d63e0)
|
||||||
|
D 6 (#178cf3)
|
||||||
|
L 5 (#75b1b0)
|
||||||
|
D 5 (#178cf1)
|
||||||
|
L 6 (#11d550)
|
||||||
|
D 6 (#44ed03)
|
||||||
|
L 3 (#76a842)
|
||||||
|
U 6 (#3b6993)
|
||||||
|
L 5 (#184892)
|
||||||
|
D 4 (#5c8163)
|
||||||
|
L 3 (#14d872)
|
||||||
|
U 2 (#261a01)
|
||||||
|
L 5 (#2d01e2)
|
||||||
|
U 9 (#326ca3)
|
||||||
|
L 4 (#59ad32)
|
||||||
|
U 8 (#326ca1)
|
||||||
|
R 4 (#389ab2)
|
||||||
|
U 9 (#261a03)
|
||||||
|
L 4 (#50cb42)
|
||||||
|
D 4 (#2f8263)
|
||||||
|
L 5 (#9f3752)
|
||||||
|
D 6 (#4bb383)
|
||||||
|
L 4 (#2693f2)
|
||||||
|
D 4 (#19dca3)
|
||||||
|
R 4 (#475bc2)
|
||||||
|
D 6 (#960e13)
|
||||||
|
L 7 (#0c90a2)
|
||||||
|
D 8 (#3463d3)
|
||||||
|
L 6 (#5a82e2)
|
||||||
|
D 3 (#5a5c43)
|
||||||
|
R 7 (#120bf2)
|
||||||
|
D 3 (#5069e3)
|
||||||
|
R 3 (#4b47a2)
|
||||||
|
D 6 (#635b63)
|
||||||
|
R 4 (#66ca10)
|
||||||
|
U 4 (#1418f1)
|
||||||
|
R 7 (#1d5470)
|
||||||
|
D 4 (#1418f3)
|
||||||
|
R 8 (#66d4f0)
|
||||||
|
D 5 (#3c5533)
|
||||||
|
R 4 (#2f6e02)
|
||||||
|
D 3 (#2cf5e3)
|
||||||
|
R 4 (#633ec2)
|
||||||
|
D 7 (#2cf5e1)
|
||||||
|
R 7 (#5846b2)
|
||||||
|
D 3 (#4f9d63)
|
||||||
|
R 4 (#533380)
|
||||||
|
D 11 (#13c7e3)
|
||||||
|
R 2 (#222b62)
|
||||||
|
D 3 (#928ab3)
|
||||||
|
R 5 (#222b60)
|
||||||
|
U 5 (#0a4793)
|
||||||
|
R 5 (#15d3b0)
|
||||||
|
U 8 (#363fe1)
|
||||||
|
R 4 (#2feb30)
|
||||||
|
U 5 (#05d8b1)
|
||||||
|
R 3 (#39e030)
|
||||||
|
U 3 (#05d8b3)
|
||||||
|
R 2 (#3cd780)
|
||||||
|
U 8 (#02c781)
|
||||||
|
R 5 (#186452)
|
||||||
|
D 3 (#37bba1)
|
||||||
|
R 5 (#9e1232)
|
||||||
|
D 5 (#58e6f1)
|
||||||
|
R 5 (#182c30)
|
||||||
|
D 5 (#072db1)
|
||||||
|
R 5 (#85e600)
|
||||||
|
D 4 (#607651)
|
||||||
|
R 5 (#186450)
|
||||||
|
D 3 (#0aca91)
|
||||||
|
L 5 (#0ceb10)
|
||||||
|
D 5 (#860001)
|
||||||
|
L 6 (#54c8b0)
|
||||||
|
U 5 (#393971)
|
||||||
|
L 4 (#37c390)
|
||||||
|
D 3 (#1f1433)
|
||||||
|
L 5 (#3d8790)
|
||||||
|
D 6 (#353623)
|
||||||
|
R 4 (#78c830)
|
||||||
|
D 4 (#6fafa3)
|
||||||
|
R 6 (#2b0612)
|
||||||
|
D 5 (#31fff3)
|
||||||
|
R 7 (#8b49b2)
|
||||||
|
D 9 (#6f0ee3)
|
||||||
|
R 5 (#4212e0)
|
||||||
|
D 6 (#5d11f3)
|
||||||
|
R 6 (#648340)
|
||||||
|
D 8 (#393743)
|
||||||
|
R 6 (#34ddd0)
|
||||||
|
U 8 (#346fb3)
|
||||||
|
R 5 (#34fc22)
|
||||||
|
D 4 (#71c453)
|
||||||
|
R 6 (#5048f2)
|
||||||
|
D 4 (#0bb993)
|
||||||
|
R 4 (#42b9f0)
|
||||||
|
D 9 (#5cdf83)
|
||||||
|
R 5 (#42b9f2)
|
||||||
|
D 3 (#6f3f93)
|
||||||
|
R 3 (#3dbae2)
|
||||||
|
D 8 (#495363)
|
||||||
|
R 9 (#328ba2)
|
||||||
|
D 3 (#77afa1)
|
||||||
|
R 5 (#575710)
|
||||||
|
D 2 (#10d861)
|
||||||
|
R 4 (#257822)
|
||||||
|
D 4 (#6efe61)
|
||||||
|
R 9 (#257820)
|
||||||
|
D 5 (#521d01)
|
||||||
|
R 5 (#575712)
|
||||||
|
D 6 (#494cf1)
|
||||||
|
L 5 (#683ab2)
|
||||||
|
D 4 (#5e79c3)
|
||||||
|
L 3 (#4242a2)
|
||||||
|
D 4 (#5e79c1)
|
||||||
|
L 7 (#2c3442)
|
||||||
|
D 8 (#2fbd23)
|
||||||
|
L 5 (#636fb2)
|
||||||
|
D 5 (#63bd53)
|
||||||
|
L 2 (#299960)
|
||||||
|
D 6 (#31ea33)
|
||||||
|
R 3 (#51dfb0)
|
||||||
|
D 7 (#4e4ec3)
|
||||||
|
R 4 (#7b7912)
|
||||||
|
D 5 (#4b4bf3)
|
||||||
|
R 4 (#54e882)
|
||||||
|
D 5 (#7d2193)
|
||||||
|
R 3 (#3b77d2)
|
||||||
|
D 3 (#826973)
|
||||||
|
R 8 (#646ec2)
|
||||||
|
D 4 (#076c63)
|
||||||
|
L 10 (#674052)
|
||||||
|
D 6 (#3676b1)
|
||||||
|
L 9 (#3bd890)
|
||||||
|
D 4 (#7feb71)
|
||||||
|
L 3 (#3bd892)
|
||||||
|
D 3 (#27fc21)
|
||||||
|
R 8 (#66bba2)
|
||||||
|
D 8 (#645c73)
|
||||||
|
R 5 (#43e132)
|
||||||
|
D 5 (#51d9e3)
|
||||||
|
R 8 (#43e130)
|
||||||
|
D 6 (#2827f3)
|
||||||
|
R 4 (#412c92)
|
||||||
|
D 5 (#7e7f63)
|
||||||
|
L 4 (#218122)
|
||||||
|
D 4 (#546e83)
|
||||||
|
L 9 (#82f672)
|
||||||
|
D 8 (#6ed383)
|
||||||
|
L 3 (#701412)
|
||||||
|
D 7 (#47de23)
|
||||||
|
L 5 (#46f912)
|
||||||
|
D 7 (#0d9ec3)
|
||||||
|
L 4 (#515142)
|
||||||
|
D 3 (#4699e3)
|
||||||
|
L 9 (#2ed562)
|
||||||
|
U 6 (#00a273)
|
||||||
|
L 9 (#8d7d12)
|
||||||
|
U 2 (#6c3a83)
|
||||||
|
L 7 (#318fa2)
|
||||||
|
U 7 (#0bd473)
|
||||||
|
L 2 (#6d5050)
|
||||||
|
U 10 (#415673)
|
||||||
|
R 3 (#9e8420)
|
||||||
|
U 6 (#1ff213)
|
||||||
|
R 5 (#0c8bf0)
|
||||||
|
U 2 (#479a11)
|
||||||
|
R 6 (#977360)
|
||||||
|
U 5 (#479a13)
|
||||||
|
L 8 (#250680)
|
||||||
|
U 2 (#1ff211)
|
||||||
|
L 3 (#216630)
|
||||||
|
U 3 (#22d143)
|
||||||
|
L 3 (#3b4342)
|
||||||
|
U 7 (#9d4ff3)
|
||||||
|
L 5 (#43aca2)
|
||||||
|
U 6 (#29efd3)
|
||||||
|
L 3 (#5c6a12)
|
||||||
|
D 11 (#134a73)
|
||||||
|
L 6 (#2a0982)
|
||||||
|
U 11 (#444723)
|
||||||
|
L 4 (#47e2e2)
|
||||||
|
U 4 (#6855c3)
|
||||||
|
L 4 (#06a382)
|
||||||
|
U 4 (#2222e3)
|
||||||
|
R 3 (#4edc62)
|
||||||
|
U 6 (#9a2683)
|
||||||
|
R 6 (#131872)
|
||||||
|
U 10 (#4f5a23)
|
||||||
|
R 4 (#858f70)
|
||||||
|
U 5 (#4d4823)
|
||||||
|
L 9 (#3f73f0)
|
||||||
|
U 3 (#46f5a3)
|
||||||
|
L 4 (#935370)
|
||||||
|
U 4 (#46f5a1)
|
||||||
|
L 5 (#3ca140)
|
||||||
|
U 6 (#07b1e3)
|
||||||
|
L 5 (#61ecd0)
|
||||||
|
U 5 (#654743)
|
||||||
|
L 5 (#3cec42)
|
||||||
|
U 6 (#30bb83)
|
||||||
|
R 3 (#920782)
|
||||||
|
U 6 (#1f9323)
|
||||||
|
R 8 (#3d8aa2)
|
||||||
|
U 8 (#7492c3)
|
||||||
|
R 3 (#301cd2)
|
||||||
|
U 3 (#32e2f1)
|
||||||
|
R 4 (#6936f2)
|
||||||
|
U 6 (#32e2f3)
|
||||||
|
R 6 (#5112c2)
|
||||||
|
U 7 (#535b53)
|
||||||
|
L 10 (#61f4d0)
|
||||||
|
U 3 (#915863)
|
||||||
|
L 2 (#51d540)
|
||||||
|
U 5 (#32dee1)
|
||||||
|
L 10 (#4ec320)
|
||||||
|
U 5 (#406bc1)
|
||||||
|
L 2 (#1b3890)
|
||||||
|
U 3 (#681181)
|
||||||
|
L 6 (#35ed60)
|
||||||
|
D 9 (#153fd3)
|
||||||
|
L 5 (#323e30)
|
||||||
|
U 5 (#381ad3)
|
||||||
|
L 3 (#69a550)
|
||||||
|
U 3 (#310f63)
|
||||||
|
L 4 (#2cbb80)
|
||||||
|
U 5 (#3448a3)
|
||||||
|
R 6 (#206282)
|
||||||
|
U 5 (#202ab1)
|
||||||
|
L 6 (#83af82)
|
||||||
|
U 4 (#202ab3)
|
||||||
|
L 4 (#248d02)
|
||||||
|
D 9 (#28a983)
|
||||||
|
L 4 (#32cf10)
|
||||||
|
D 7 (#249d73)
|
||||||
|
R 4 (#2f5c70)
|
||||||
|
D 6 (#021c93)
|
||||||
|
L 7 (#957782)
|
||||||
|
D 6 (#550e53)
|
||||||
|
R 5 (#957780)
|
||||||
|
D 6 (#50bb13)
|
||||||
|
R 9 (#49b7f2)
|
||||||
|
U 6 (#096e93)
|
||||||
|
R 4 (#769452)
|
||||||
|
D 3 (#6dc543)
|
||||||
|
R 5 (#2ad352)
|
||||||
|
D 7 (#167963)
|
||||||
|
L 10 (#673682)
|
||||||
|
D 5 (#152883)
|
||||||
|
L 10 (#13f332)
|
||||||
|
D 3 (#996721)
|
||||||
|
L 4 (#4be2a2)
|
||||||
|
D 4 (#9c2443)
|
||||||
|
L 4 (#2b83b0)
|
||||||
|
D 3 (#5d63b3)
|
||||||
|
L 9 (#9cfd40)
|
||||||
|
D 7 (#49e793)
|
||||||
|
L 7 (#0b5422)
|
||||||
|
D 8 (#5c51b3)
|
||||||
|
L 2 (#6db152)
|
||||||
|
D 4 (#215b53)
|
||||||
|
L 3 (#38dc12)
|
||||||
|
D 8 (#7dad01)
|
||||||
|
L 6 (#559e22)
|
||||||
|
D 3 (#929d23)
|
||||||
|
L 2 (#0f7560)
|
||||||
|
D 6 (#448d13)
|
||||||
|
L 7 (#73a972)
|
||||||
|
D 2 (#2221c3)
|
||||||
|
L 3 (#73a970)
|
||||||
|
D 5 (#53b553)
|
||||||
|
R 10 (#513590)
|
||||||
|
D 3 (#293c83)
|
||||||
|
L 10 (#58e2e0)
|
||||||
|
D 4 (#54dd21)
|
||||||
|
L 5 (#1bcdf2)
|
||||||
|
D 5 (#4b0b71)
|
||||||
|
L 5 (#1bcdf0)
|
||||||
|
U 6 (#43b811)
|
||||||
|
L 5 (#4df1d0)
|
||||||
|
U 6 (#36d6a3)
|
||||||
|
R 5 (#3bfb20)
|
||||||
|
U 5 (#75de61)
|
||||||
|
L 5 (#1e0ec2)
|
||||||
|
U 4 (#30b571)
|
||||||
|
L 7 (#2dfd20)
|
||||||
|
D 5 (#49ad61)
|
||||||
|
L 2 (#2dfd22)
|
||||||
|
D 11 (#715d41)
|
||||||
|
L 3 (#1e0ec0)
|
||||||
|
U 4 (#0f2091)
|
||||||
|
L 4 (#9d29c0)
|
||||||
|
U 9 (#475a73)
|
||||||
|
L 2 (#108610)
|
||||||
|
U 3 (#1e5423)
|
||||||
|
L 8 (#394192)
|
||||||
|
U 3 (#0274b3)
|
||||||
89
aoc2023/day18/main.go
Normal file
89
aoc2023/day18/main.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
aoc "go.sour.is/advent-of-code"
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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 vecsPT1 []aoc.Vector
|
||||||
|
var vecsPT2 []aoc.Vector
|
||||||
|
|
||||||
|
for scan.Scan() {
|
||||||
|
text := scan.Text()
|
||||||
|
|
||||||
|
if len(text) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
v, color := fromLine(text)
|
||||||
|
|
||||||
|
vecsPT1 = append(vecsPT1, v)
|
||||||
|
vecsPT2 = append(vecsPT2, fromColor(color))
|
||||||
|
}
|
||||||
|
return &result{
|
||||||
|
valuePT1: findArea(vecsPT1),
|
||||||
|
valuePT2: findArea(vecsPT2),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var OFFSET = map[string]aoc.Point[int]{
|
||||||
|
"R": {0, 1},
|
||||||
|
"D": {1, 0},
|
||||||
|
"L": {0, -1},
|
||||||
|
"U": {-1, 0},
|
||||||
|
}
|
||||||
|
var OFFSET_INDEXES = maps.Values(OFFSET)
|
||||||
|
|
||||||
|
func fromLine(text string) (aoc.Vector, string) {
|
||||||
|
v := aoc.Vector{}
|
||||||
|
s, text, _ := strings.Cut(text, " ")
|
||||||
|
v.Offset = OFFSET[s]
|
||||||
|
|
||||||
|
s, text, _ = strings.Cut(text, " ")
|
||||||
|
v.Scale = aoc.Atoi(s)
|
||||||
|
|
||||||
|
_, text, _ = strings.Cut(text, "(#")
|
||||||
|
s, _, _ = strings.Cut(text, ")")
|
||||||
|
return v, s
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromColor(c string) aoc.Vector {
|
||||||
|
scale, _ := strconv.ParseInt(c[:5], 16, 64)
|
||||||
|
offset := OFFSET_INDEXES[c[5]-'0']
|
||||||
|
|
||||||
|
return aoc.Vector{
|
||||||
|
Offset: offset,
|
||||||
|
Scale: int(scale),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func findArea(vecs []aoc.Vector) int {
|
||||||
|
shoelace := []aoc.Point[int]{{0, 0}}
|
||||||
|
borderLength := 0
|
||||||
|
|
||||||
|
for _, vec := range vecs {
|
||||||
|
shoelace = append(shoelace, shoelace[len(shoelace)-1].Add(vec.Point()))
|
||||||
|
borderLength += vec.Scale
|
||||||
|
}
|
||||||
|
|
||||||
|
return aoc.NumPoints(shoelace, borderLength)
|
||||||
|
}
|
||||||
42
aoc2023/day18/main_test.go
Normal file
42
aoc2023/day18/main_test.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
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, 62)
|
||||||
|
is.Equal(result.valuePT2, 952408144115)
|
||||||
|
}
|
||||||
|
|
||||||
|
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.True(result.valuePT1 < 68834) // first attempt too high.
|
||||||
|
is.Equal(result.valuePT1, 46334)
|
||||||
|
is.Equal(result.valuePT2, 102000662718092)
|
||||||
|
}
|
||||||
255
aoc2023/day19/main.go
Normal file
255
aoc2023/day19/main.go
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
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 uint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r result) String() string { return fmt.Sprintf("%#v", r) }
|
||||||
|
|
||||||
|
func run(scan *bufio.Scanner) (*result, error) {
|
||||||
|
|
||||||
|
var workflows = make(map[string][]rule)
|
||||||
|
var parts []part
|
||||||
|
|
||||||
|
for scan.Scan() {
|
||||||
|
text := strings.TrimSuffix(scan.Text(), "}")
|
||||||
|
if len(text) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is Part
|
||||||
|
if p, ok := scanPart(text); ok {
|
||||||
|
parts = append(parts, p)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if name, r, ok := scanRule(text); ok {
|
||||||
|
workflows[name] = r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result result
|
||||||
|
result.valuePT1 = solveWorkflow(parts, workflows)
|
||||||
|
result.valuePT2 = solveRanges(workflows)
|
||||||
|
|
||||||
|
return &result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type part struct {
|
||||||
|
x, m, a, s int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p part) String() string {
|
||||||
|
return fmt.Sprintf("{x:%v m:%v a:%v s:%v}", p.x, p.m, p.a, p.s)
|
||||||
|
}
|
||||||
|
func scanPart(text string) (part, bool) {
|
||||||
|
var p part
|
||||||
|
|
||||||
|
// Is Part
|
||||||
|
if text[0] == '{' {
|
||||||
|
for _, s := range strings.Split(text[1:], ",") {
|
||||||
|
a, b, _ := strings.Cut(s, "=")
|
||||||
|
i := aoc.Atoi(b)
|
||||||
|
switch a {
|
||||||
|
case "x":
|
||||||
|
p.x = i
|
||||||
|
case "m":
|
||||||
|
p.m = i
|
||||||
|
case "a":
|
||||||
|
p.a = i
|
||||||
|
case "s":
|
||||||
|
p.s = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p, true
|
||||||
|
}
|
||||||
|
return p, false
|
||||||
|
}
|
||||||
|
|
||||||
|
type rule struct {
|
||||||
|
match string
|
||||||
|
op string
|
||||||
|
value int
|
||||||
|
queue string
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanRule(text string) (string, []rule, bool) {
|
||||||
|
name, text, _ := strings.Cut(text, "{")
|
||||||
|
var r []rule
|
||||||
|
for _, s := range strings.Split(text, ",") {
|
||||||
|
if a, b, ok := strings.Cut(s, "<"); ok {
|
||||||
|
b, c, _ := strings.Cut(b, ":")
|
||||||
|
r = append(r, rule{
|
||||||
|
match: a,
|
||||||
|
op: "<",
|
||||||
|
value: aoc.Atoi(b),
|
||||||
|
queue: c,
|
||||||
|
})
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if a, b, ok := strings.Cut(s, ">"); ok {
|
||||||
|
b, c, _ := strings.Cut(b, ":")
|
||||||
|
r = append(r, rule{
|
||||||
|
match: a,
|
||||||
|
op: ">",
|
||||||
|
value: aoc.Atoi(b),
|
||||||
|
queue: c,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// default queue comes last
|
||||||
|
r = append(r, rule{queue: s})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return name, r, len(r) > 0
|
||||||
|
}
|
||||||
|
func (r rule) Match(p part) bool {
|
||||||
|
var value int
|
||||||
|
|
||||||
|
switch r.match {
|
||||||
|
case "x":
|
||||||
|
value = p.x
|
||||||
|
case "m":
|
||||||
|
value = p.m
|
||||||
|
case "a":
|
||||||
|
value = p.a
|
||||||
|
case "s":
|
||||||
|
value = p.s
|
||||||
|
default:
|
||||||
|
return true // default to new queue
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.op == ">" && value > r.value {
|
||||||
|
return true
|
||||||
|
} else if r.op == "<" && value < r.value {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false // no match
|
||||||
|
}
|
||||||
|
|
||||||
|
func solveWorkflow(parts []part, workflows map[string][]rule) int {
|
||||||
|
// var rejected []part
|
||||||
|
var accepted []part
|
||||||
|
|
||||||
|
for _, p := range parts {
|
||||||
|
workflow := "in"
|
||||||
|
|
||||||
|
nextStep:
|
||||||
|
for workflow != "" {
|
||||||
|
for _, r := range workflows[workflow] {
|
||||||
|
if !r.Match(p) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
workflow = r.queue
|
||||||
|
|
||||||
|
if workflow == "A" {
|
||||||
|
accepted = append(accepted, p)
|
||||||
|
workflow = ""
|
||||||
|
break nextStep
|
||||||
|
}
|
||||||
|
if workflow == "R" {
|
||||||
|
// rejected = append(rejected, p)
|
||||||
|
workflow = ""
|
||||||
|
break nextStep
|
||||||
|
}
|
||||||
|
|
||||||
|
continue nextStep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sum := 0
|
||||||
|
for _, p := range accepted {
|
||||||
|
sum += p.x
|
||||||
|
sum += p.m
|
||||||
|
sum += p.a
|
||||||
|
sum += p.s
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
func solveRanges(workflows map[string][]rule) uint {
|
||||||
|
|
||||||
|
pq := aoc.PriorityQueue(func(a, b *queue) bool { return false })
|
||||||
|
pq.Insert(&queue{
|
||||||
|
"in",
|
||||||
|
block{
|
||||||
|
ranger{1, 4000},
|
||||||
|
ranger{1, 4000},
|
||||||
|
ranger{1, 4000},
|
||||||
|
ranger{1, 4000},
|
||||||
|
}})
|
||||||
|
|
||||||
|
var accepted []block
|
||||||
|
// var rejected []block
|
||||||
|
|
||||||
|
for !pq.IsEmpty() {
|
||||||
|
current := pq.ExtractMin()
|
||||||
|
for _, rule := range workflows[current.name] {
|
||||||
|
next := &queue{name: rule.queue, block: current.block}
|
||||||
|
|
||||||
|
switch rule.match {
|
||||||
|
case "x":
|
||||||
|
current.x, next.x = split(current.x, rule.value, rule.op == ">")
|
||||||
|
case "m":
|
||||||
|
current.m, next.m = split(current.m, rule.value, rule.op == ">")
|
||||||
|
case "a":
|
||||||
|
current.a, next.a = split(current.a, rule.value, rule.op == ">")
|
||||||
|
case "s":
|
||||||
|
current.s, next.s = split(current.s, rule.value, rule.op == ">")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch next.name {
|
||||||
|
case "R":
|
||||||
|
// rejected = append(rejected, next.block)
|
||||||
|
|
||||||
|
case "A":
|
||||||
|
accepted = append(accepted, next.block)
|
||||||
|
|
||||||
|
default:
|
||||||
|
pq.Insert(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sum uint
|
||||||
|
for _, a := range accepted {
|
||||||
|
sum += uint((a.x[1] - a.x[0] + 1) * (a.m[1] - a.m[0] + 1) * (a.a[1] - a.a[0] + 1) * (a.s[1] - a.s[0] + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
type ranger [2]int
|
||||||
|
type block struct {
|
||||||
|
x, m, a, s ranger
|
||||||
|
}
|
||||||
|
type queue struct {
|
||||||
|
name string
|
||||||
|
block
|
||||||
|
}
|
||||||
|
|
||||||
|
func split(a ranger, n int, gt bool) (current ranger, next ranger) {
|
||||||
|
if gt { // x > N => [0,N] [N++,inf]
|
||||||
|
return ranger{a[0], n}, ranger{n + 1, a[1]}
|
||||||
|
}
|
||||||
|
|
||||||
|
// x < N => [N,inf] [0,N--]
|
||||||
|
return ranger{n, a[1]}, ranger{a[0], n - 1}
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ func TestExample(t *testing.T) {
|
|||||||
|
|
||||||
t.Log(result)
|
t.Log(result)
|
||||||
is.Equal(result.valuePT1, 19114)
|
is.Equal(result.valuePT1, 19114)
|
||||||
is.Equal(result.valuePT2, 0)
|
is.Equal(result.valuePT2, uint(167409079868000))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSolution(t *testing.T) {
|
func TestSolution(t *testing.T) {
|
||||||
@@ -37,5 +37,5 @@ func TestSolution(t *testing.T) {
|
|||||||
|
|
||||||
t.Log(result)
|
t.Log(result)
|
||||||
is.Equal(result.valuePT1, 377025)
|
is.Equal(result.valuePT1, 377025)
|
||||||
is.Equal(result.valuePT2, 0)
|
is.Equal(result.valuePT2, uint(135506683246673))
|
||||||
}
|
}
|
||||||
5
aoc2023/day20/example1.txt
Normal file
5
aoc2023/day20/example1.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
broadcaster -> a, b, c
|
||||||
|
%a -> b
|
||||||
|
%b -> c
|
||||||
|
%c -> inv
|
||||||
|
&inv -> a
|
||||||
5
aoc2023/day20/example2.txt
Normal file
5
aoc2023/day20/example2.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
broadcaster -> a
|
||||||
|
%a -> inv, con
|
||||||
|
&inv -> b
|
||||||
|
%b -> con
|
||||||
|
&con -> output
|
||||||
58
aoc2023/day20/input.txt
Normal file
58
aoc2023/day20/input.txt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
%vg -> lf, vd
|
||||||
|
%dr -> kg
|
||||||
|
%cn -> mv, pt
|
||||||
|
%rq -> bk, gr
|
||||||
|
%vp -> lp, bk
|
||||||
|
%kg -> lv
|
||||||
|
%lv -> jc, tp
|
||||||
|
%sj -> rm, vd
|
||||||
|
%jc -> tp, qr
|
||||||
|
%km -> tp, dr
|
||||||
|
%jx -> cn
|
||||||
|
&vd -> tf, lf, nb, cx, hx, lr
|
||||||
|
%lp -> jt, bk
|
||||||
|
%vj -> ps
|
||||||
|
broadcaster -> km, lr, xh, rf
|
||||||
|
%dj -> pt, gc
|
||||||
|
%cg -> vd, hx
|
||||||
|
&ln -> tg
|
||||||
|
%fl -> pt, sk
|
||||||
|
%lm -> tr, bk
|
||||||
|
%lr -> vd, vg
|
||||||
|
&pt -> vq, rf, cm, jx, rg
|
||||||
|
%cx -> gp
|
||||||
|
%gp -> vd, sj
|
||||||
|
&db -> tg
|
||||||
|
%st -> vd
|
||||||
|
%jt -> bk
|
||||||
|
%jh -> lm, bk
|
||||||
|
%xf -> bd, tp
|
||||||
|
%gc -> cm, pt
|
||||||
|
&tp -> dr, km, kg, db, vj, qr
|
||||||
|
%ps -> xf, tp
|
||||||
|
%rf -> pt, dj
|
||||||
|
%lf -> nb
|
||||||
|
%bd -> tp, gg
|
||||||
|
%dk -> tp, vj
|
||||||
|
%mn -> jh, bk
|
||||||
|
&tg -> rx
|
||||||
|
%ql -> bk, zx
|
||||||
|
%tr -> bk, vp
|
||||||
|
%sk -> pt
|
||||||
|
%nb -> cg
|
||||||
|
%sb -> vd, cx
|
||||||
|
%qr -> dk
|
||||||
|
%xh -> bk, ql
|
||||||
|
%rg -> sd
|
||||||
|
%hx -> sb
|
||||||
|
%sd -> pt, jx
|
||||||
|
%gr -> bk, mn
|
||||||
|
%gg -> tp
|
||||||
|
%zx -> rq
|
||||||
|
&bk -> xh, ln, zx
|
||||||
|
%rm -> st, vd
|
||||||
|
%hq -> fl, pt
|
||||||
|
&vq -> tg
|
||||||
|
%cm -> rg
|
||||||
|
&tf -> tg
|
||||||
|
%mv -> pt, hq
|
||||||
282
aoc2023/day20/main.go
Normal file
282
aoc2023/day20/main.go
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
aoc "go.sour.is/advent-of-code"
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
m := &machine{}
|
||||||
|
receivers := make(map[string][]string)
|
||||||
|
|
||||||
|
for scan.Scan() {
|
||||||
|
text := scan.Text()
|
||||||
|
|
||||||
|
name, text, _ := strings.Cut(text, " -> ")
|
||||||
|
dest := strings.Split(text, ", ")
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case name == "broadcaster":
|
||||||
|
m.Add(name, &broadcaster{dest: dest})
|
||||||
|
case strings.HasPrefix(name, "%"):
|
||||||
|
name = strings.TrimPrefix(name, "%")
|
||||||
|
m.Add(name, &flipflop{name: name, dest: dest})
|
||||||
|
|
||||||
|
case strings.HasPrefix(name, "&"):
|
||||||
|
name = strings.TrimPrefix(name, "&")
|
||||||
|
m.Add(name, &conjunction{name: name, dest: dest})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range dest {
|
||||||
|
// rx is present so enable pt 2
|
||||||
|
if d == "rx" {
|
||||||
|
m.Add("rx", &rx{})
|
||||||
|
}
|
||||||
|
receivers[d] = append(receivers[d], name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m.setup(receivers)
|
||||||
|
|
||||||
|
result := &result{}
|
||||||
|
|
||||||
|
for i := 0; i < 10_000; i++ { // need enough presses to find the best LCM values for each conjunction
|
||||||
|
if i == 1000 {
|
||||||
|
result.valuePT1 = m.highPulses * m.lowPulses
|
||||||
|
}
|
||||||
|
m.Push(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rx is present.. perform part 2.
|
||||||
|
if rx, ok := receivers["rx"]; ok {
|
||||||
|
tip := m.m[rx[0]].(*conjunction) // panic if missing!
|
||||||
|
|
||||||
|
var lvalues []int
|
||||||
|
for k, v := range tip.pushes {
|
||||||
|
for i, h := range makeHistory(v) {
|
||||||
|
if i == 1 && len(h) > 0 && h[0] > 0 {
|
||||||
|
fmt.Println(tip.name, k, "frequency", h[0])
|
||||||
|
lvalues = append(lvalues, h[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.valuePT2 = aoc.LCM(lvalues...)
|
||||||
|
fmt.Println(tip.name, "LCM", result.valuePT2, lvalues)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type signal bool
|
||||||
|
|
||||||
|
const (
|
||||||
|
LOW signal = false
|
||||||
|
HIGH signal = true
|
||||||
|
)
|
||||||
|
|
||||||
|
type message struct {
|
||||||
|
signal
|
||||||
|
from, to string
|
||||||
|
}
|
||||||
|
|
||||||
|
type machine struct {
|
||||||
|
m map[string]pulser
|
||||||
|
|
||||||
|
queue []message
|
||||||
|
|
||||||
|
press int
|
||||||
|
highPulses int
|
||||||
|
lowPulses int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *machine) Add(name string, p pulser) {
|
||||||
|
if m.m == nil {
|
||||||
|
m.m = make(map[string]pulser)
|
||||||
|
}
|
||||||
|
p.SetMachine(m)
|
||||||
|
m.m[name] = p
|
||||||
|
}
|
||||||
|
func (m *machine) Send(msgs ...message) {
|
||||||
|
m.queue = append(m.queue, msgs...)
|
||||||
|
for _, msg := range msgs {
|
||||||
|
// fmt.Println(msg)
|
||||||
|
if msg.signal {
|
||||||
|
m.highPulses++
|
||||||
|
} else {
|
||||||
|
m.lowPulses++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (m *machine) Push(i int) {
|
||||||
|
m.press = i
|
||||||
|
m.Send(generate(LOW, "button", "broadcaster")...)
|
||||||
|
m.processQueue(i)
|
||||||
|
}
|
||||||
|
func (m *machine) processQueue(i int) {
|
||||||
|
// look for work and process up to the queue length. repeat.
|
||||||
|
hwm := 0
|
||||||
|
for hwm < len(m.queue) {
|
||||||
|
end := len(m.queue)
|
||||||
|
|
||||||
|
for ; hwm < end; hwm++ {
|
||||||
|
msg := m.queue[hwm]
|
||||||
|
|
||||||
|
if p, ok := m.m[msg.to]; ok {
|
||||||
|
// fmt.Println(i, "S:", m.m[msg.from], msg.signal, "R:", p)
|
||||||
|
p.Pulse(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hwm = 0
|
||||||
|
copy(m.queue, m.queue[end:])
|
||||||
|
m.queue = m.queue[:len(m.queue)-end]
|
||||||
|
// fmt.Println("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (m *machine) setup(receivers map[string][]string) {
|
||||||
|
for name, recv := range receivers {
|
||||||
|
if p, ok := m.m[name]; ok {
|
||||||
|
if p, ok := p.(interface{ Receive(...string) }); ok {
|
||||||
|
p.Receive(recv...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type pulser interface {
|
||||||
|
Pulse(message)
|
||||||
|
SetMachine(*machine)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsModule implements the machine registration for each module.
|
||||||
|
type IsModule struct {
|
||||||
|
*machine
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *IsModule) SetMachine(m *machine) { p.machine = m }
|
||||||
|
|
||||||
|
type broadcaster struct {
|
||||||
|
dest []string
|
||||||
|
IsModule
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *broadcaster) Pulse(msg message) {
|
||||||
|
b.Send(generate(msg.signal, "broadcaster", b.dest...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type flipflop struct {
|
||||||
|
name string
|
||||||
|
state signal
|
||||||
|
dest []string
|
||||||
|
|
||||||
|
IsModule
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *flipflop) Pulse(msg message) {
|
||||||
|
if !msg.signal {
|
||||||
|
b.state = !b.state
|
||||||
|
b.Send(generate(b.state, b.name, b.dest...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type conjunction struct {
|
||||||
|
name string
|
||||||
|
state map[string]signal
|
||||||
|
dest []string
|
||||||
|
|
||||||
|
pushes map[string][]int
|
||||||
|
|
||||||
|
IsModule
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *conjunction) Receive(names ...string) {
|
||||||
|
if b.state == nil {
|
||||||
|
b.state = make(map[string]signal)
|
||||||
|
b.pushes = make(map[string][]int)
|
||||||
|
}
|
||||||
|
for _, name := range names {
|
||||||
|
b.state[name] = false
|
||||||
|
b.pushes[name] = []int{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (b *conjunction) Pulse(msg message) {
|
||||||
|
b.state[msg.from] = msg.signal
|
||||||
|
|
||||||
|
if msg.signal {
|
||||||
|
// collect frequency of pushes to esti,ate rate
|
||||||
|
b.pushes[msg.from] = append(b.pushes[msg.from], b.press)
|
||||||
|
}
|
||||||
|
|
||||||
|
if all(HIGH, maps.Values(b.state)...) {
|
||||||
|
b.Send(generate(LOW, b.name, b.dest...)...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.Send(generate(HIGH, b.name, b.dest...)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type rx struct {
|
||||||
|
IsModule
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rx *rx) Pulse(msg message) {
|
||||||
|
if !msg.signal {
|
||||||
|
panic("pulse received") // will never happen...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper funcs
|
||||||
|
func all[T comparable](match T, lis ...T) bool {
|
||||||
|
for _, b := range lis {
|
||||||
|
if b != match {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
func generate(t signal, from string, destinations ...string) []message {
|
||||||
|
msgs := make([]message, len(destinations))
|
||||||
|
for i, to := range destinations {
|
||||||
|
msgs[i] = message{signal: t, from: from, to: to}
|
||||||
|
}
|
||||||
|
return msgs
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeHistory from day 9
|
||||||
|
func makeHistory(in []int) [][]int {
|
||||||
|
var history [][]int
|
||||||
|
history = append(history, in)
|
||||||
|
|
||||||
|
// for {
|
||||||
|
var diffs []int
|
||||||
|
|
||||||
|
current := history[len(history)-1]
|
||||||
|
|
||||||
|
for i := range current[1:] {
|
||||||
|
diffs = append(diffs, current[i+1]-current[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
history = append(history, diffs)
|
||||||
|
|
||||||
|
// if len(diffs) == 0 || aoc.Max(diffs[0], diffs[1:]...) == 0 && aoc.Min(diffs[0], diffs[1:]...) == 0 {
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return history
|
||||||
|
}
|
||||||
56
aoc2023/day20/main_test.go
Normal file
56
aoc2023/day20/main_test.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
|
|
||||||
|
"github.com/matryer/is"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed example1.txt
|
||||||
|
var example1 []byte
|
||||||
|
|
||||||
|
//go:embed example2.txt
|
||||||
|
var example2 []byte
|
||||||
|
|
||||||
|
//go:embed input.txt
|
||||||
|
var input []byte
|
||||||
|
|
||||||
|
func TestExample1(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
scan := bufio.NewScanner(bytes.NewReader(example1))
|
||||||
|
|
||||||
|
result, err := run(scan)
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
t.Log(result)
|
||||||
|
is.Equal(result.valuePT1, 32000000)
|
||||||
|
is.Equal(result.valuePT2, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExample2(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
scan := bufio.NewScanner(bytes.NewReader(example2))
|
||||||
|
|
||||||
|
result, err := run(scan)
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
t.Log(result)
|
||||||
|
is.Equal(result.valuePT1, 11687500)
|
||||||
|
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, 819397964)
|
||||||
|
is.Equal(result.valuePT2, 252667369442479)
|
||||||
|
}
|
||||||
11
aoc2023/day21/example.txt
Normal file
11
aoc2023/day21/example.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
...........
|
||||||
|
.....###.#.
|
||||||
|
.###.##..#.
|
||||||
|
..#.#...#..
|
||||||
|
....#.#....
|
||||||
|
.##..S####.
|
||||||
|
.##..#...#.
|
||||||
|
.......##..
|
||||||
|
.##.#.####.
|
||||||
|
.##..##.##.
|
||||||
|
...........
|
||||||
131
aoc2023/day21/input.txt
Normal file
131
aoc2023/day21/input.txt
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
...................................................................................................................................
|
||||||
|
.#.......#..#...#.......#......#....#..#...#...#....#.#..........................................#...............#..........#......
|
||||||
|
.............##..................#......#.#....#.......................##..#........................#......#..........#............
|
||||||
|
......#..........................#....#.....#.............#................##....#.#.............#.........#.##...........#........
|
||||||
|
.#................#............................#...........................#..##.....#..................#..##..#.#.........##......
|
||||||
|
.....#.............#.....##.............##..........#...........#.............#.....#...........#.#.......#....#......#..........#.
|
||||||
|
........#....................#....#.#.#......##........#...........#...........#..........#...#..........#......................#..
|
||||||
|
.........#.#...#.......#........#........##...#...#..##........................................##...#.#........................#...
|
||||||
|
......#.....#..#..#.#..#..............#...#..#.....#...........#.....#........#.#...........#...........#.#...............#.....#..
|
||||||
|
...........#.......####..#.#..............##................#.#.#.....................##.....................#...#..............#..
|
||||||
|
......###...#......#................##...#...#....#...........#...#..............#.........#..#..................................#.
|
||||||
|
...............#..##..........#...........................##......#.##.........................#..#.#...........#.#...........#....
|
||||||
|
...##........#...#...#...##...##...........#..#...................#...................#.#..#.........#.......#..#...........##...#.
|
||||||
|
................#.....#..##......#.....#.....##............#..#..........##...........................#.#.......##.....#.....#.....
|
||||||
|
.#..#.......#.#...#..##.....#............................#......#...#....#................#.#..#.....#.......##................#...
|
||||||
|
...............#.....#........................#..........#.....#..............................................#..................#.
|
||||||
|
.....#......#..........................................#....................................#..#.......#.#..#......#.#....#..##....
|
||||||
|
............##............#.......###.......................#..#....#......................................#..#.........#..........
|
||||||
|
..#...............#.....#...#...#......................#...#.#..............................#.#..#.#.....#.#.#..#....#.....#...##..
|
||||||
|
.#.............................##.................#.......#.......##....#....................#.....#.#........#.....#........#.....
|
||||||
|
.#....##...................##.....#.#..............#.#....#....#..#....#......#..........#.....##............#....#.............##.
|
||||||
|
.........#....#.....#..#.........#....#.#..........#...#...#.......#....#..##.......................#.#..#........#..#....#..#.#...
|
||||||
|
..#..................#.......#..#.#..............##.......#........#..............#.........#..#....#......#..#..........#.........
|
||||||
|
........#.....#......#.....#......#...#.......#....#.......#.#..#................#....................##.............#.......#.....
|
||||||
|
..#.................#..............#...........................................#.....#..................#...#.#..................#.
|
||||||
|
.......#......#.....#...........................#.....#..................#.....................#.....#.#......#........#.#.......#.
|
||||||
|
..#.#.#...................#...#..#................#....#.......#......................#...............#.........##...#.#.....###...
|
||||||
|
.....#...#....##....#........####...........#.................#...#...........................................#..............##....
|
||||||
|
..##.#..#.#..........#.#.#..#................................#..#.............#..#......#...........................#.##...........
|
||||||
|
..............#.............................##........#..##........................#.............................#........#........
|
||||||
|
........#.........#........#..#........#..#........#...#.#........#...........#.........................#.#..........#...#......#..
|
||||||
|
.........##.....#........#.....................#..#.............#.....#........#....................#....#.#.#......#.....#........
|
||||||
|
......................#...................####..#.........#....#.........#...........#..................#..#.................#.....
|
||||||
|
..#.........#...#.....##................##.##....#.....#....#..............................#..#.............#..#...................
|
||||||
|
..........##......#..#..............#.#....#......#................#.....#....#..............#..................#..................
|
||||||
|
.#.#..####...#....................#.#.#.....#...#...................#....#.#.....#.#.......#.#...........#......#.#................
|
||||||
|
.......#.........#..#.#..............###.......#....#.........................#.......#.###...#............#....#.#..#....###.#....
|
||||||
|
........#....#...#......#.................#..........................#.........................#...........##.............#.#......
|
||||||
|
.#..............#.....................#......#.............##............#..#..........#...................#...#....#..............
|
||||||
|
......#..#..#.#...............#........###.......#.#...........#...........#.#.........#..#.....................#......#..#.#......
|
||||||
|
.....#...............#.........#....#..........#.......#.......#......#...#..##.....#.....#........#.#.......#.......#..#...#......
|
||||||
|
..#............#.....................#...#.......#....###...........#.....#.#.................#................#.........#..##.#...
|
||||||
|
..............................#.....#..................................#.....##...............#.......#.........#.....#....##......
|
||||||
|
..#...##...#...#..............#.................##..#......#.................#....#......#...#...#......#..........................
|
||||||
|
.........#....#..............#........#..#...............#....#...#.....#..#......#.........#.......#.#..#........#...........#....
|
||||||
|
........#..#....................#.........#...##.#.#..............#......#.#..........##...##....#......................#..........
|
||||||
|
.##..#....#....#.......##......#............#..#......#.....##..................#####..#...#......#.#...#..........#.#.....#..#....
|
||||||
|
..#...........#....................#.......#......#.........#...............#......#........##........#.................#.....#.#..
|
||||||
|
..#....#.#...............#.#.........................#.............####..............................##................###.........
|
||||||
|
.....#.......................................#....#...##...#.......#.......#.....#.##..##.................#.....................##.
|
||||||
|
.........#...........#..#..##.#..........#..#.........#..#.....#...................................##....#...............#..#.#....
|
||||||
|
.....#..#...........##............#........#..................#............#..........#..........#..#...........#..................
|
||||||
|
............................#.........#...............#..................#.#....#.#..#........#.....#...........#...........#......
|
||||||
|
................#...##.#....#..##..........#.#........##.#..#..#.....................#....#.................#.#...............#....
|
||||||
|
.#.....#..............#.#..........#..#........#...............#..#.#..##..#.#.#.........................#.................#.......
|
||||||
|
....#..............#................#.....#..#.......#..#.#.........#..........#..........#.....#..........##.....#............#...
|
||||||
|
..............##...........#.......#......#..................#.......#.....#.#...#...............#.#........#......#............#..
|
||||||
|
................#.....#....#........#....#.......#.#.##.....#...#..#.##...#................#.#.....#....#.............#............
|
||||||
|
...........#.#.##..####.....#....#.#...#.#...........#...#.......................#.#....#.....#..#................###..............
|
||||||
|
...................#....#..........#.#..##.....#..#..#......###............#..#...........#....#......#............................
|
||||||
|
...........................................#.......#..............#.##.......##.......#...#.....#.#..#.....#..###..................
|
||||||
|
............###........#.......#.#....#.....#....#..#........#.........##....#.....#..........#......#............#..#.#...........
|
||||||
|
............#..........#................##.#..............#.....#................#....................................#..#.........
|
||||||
|
...........#.....#.....................#...#.....#.......#..........#....#.....###.....##.#.##.#.....#......#......#.......#.......
|
||||||
|
.....................#..#.....#...##.....#..#...........#....#....##............##.................##............##................
|
||||||
|
.................................................................S.................................................................
|
||||||
|
........#.#........#..........#.....#......#........#.#............#.#.........##...#............#...#.....#...........#.....#.....
|
||||||
|
..................##.......#......#..#..................#..##......#.........#...#.........#............#....#...........##........
|
||||||
|
..................#...........#.##.......#..............#....................#.#....#...##...#.....#.......#..#.....##.............
|
||||||
|
...........#....#....##...#................................#.........#.................#....#.......................#...#..........
|
||||||
|
.............#.#.#.....#.#...#.......#.#...........#....#.#.........#........##......#.......#.......##...#..........#.##..........
|
||||||
|
...........##.#....#....#..#.....#...............#......................#...........#.....#...........#.#.......#..................
|
||||||
|
.#.......................#.#...##.#....#.#...........#.#....##.##......#........................##....#.#....#.....................
|
||||||
|
...#..................#.#...........##....###.................#....................##......#.....#............#.##....#.......##...
|
||||||
|
.#..................####...#.#..#.##.#...####...#......#....................#..........................#....#......................
|
||||||
|
.....#..........#.....#.#...............#.........##...#......#.#.....#...........#.....#............##......#.....#...............
|
||||||
|
......#........#....#..#............................###.#...##........#........#.................#..#........#...............##....
|
||||||
|
......................#.........................##....#...#..............#..#............#.#....#......##.#......#.........##......
|
||||||
|
..................#....#...#.#.......#..............#..#..#...#.......#...#.....#.....#...............#.#.#...............#........
|
||||||
|
...#...##......................##..##...........#......#.............#............#...........##.......#....#......................
|
||||||
|
.............................##...........##...#...#.....#....#.......#.#..#.....##...............#..#.#......#..............##....
|
||||||
|
...#..#.#...#.......#..................#............#....#.#.##.#.........#......#........#..#..........#....##...........#....#...
|
||||||
|
.....#.............................#......#.#.....#.##.#.................#.........#..#..#.#.#........................#.#.......#..
|
||||||
|
....#........#........#....#.#.#.....#.##............###.#..........#...##......#........##...#.........#.............#........#...
|
||||||
|
..#..............................#.............................#......#...................#...#......#.............#...............
|
||||||
|
.......#...#...............#.................##....................#....##.......#....##....##...#..................#..............
|
||||||
|
.........................#...#..#.....##.............#...##.......#.....#...#..............#.....#.#.#..#........................#.
|
||||||
|
......#.......##.#.............#....................#...#...........#...#..##....#.....#............#...........#........#.........
|
||||||
|
...#....#...#......#........................#.....#.........#......#........#.....#.#...........#.#..............#......#....#.....
|
||||||
|
........#..........#...................#...........##.#..#...#................#....##.............#................#....#..........
|
||||||
|
........#.......#....#.............#..........#...................#.#....#.#........#..#..............................#..........#.
|
||||||
|
............#........#....................#.#.........#......#.............#................#...#.............#....#...............
|
||||||
|
..#..............................#..#....##.....#......................##...#..#.........#......#......................#...#...#.#.
|
||||||
|
.##....#.............#...........##..................#...#..............#.......#................................#.........#.......
|
||||||
|
.....#......#.#.....##...........#.....#.......#..........##..#.............#.#.........#.#.#.............##........#......#..#....
|
||||||
|
.......#.......#.#.#..#......................#....#............##....#...........#.........................#......#................
|
||||||
|
.........##.........#..............#.#.#....#...#.......#.................................#..##..................##.###.##...#.....
|
||||||
|
......................#...#.#.......#..#.#..........#........#.......#.................#..................................#........
|
||||||
|
....##........#.........#.........................#................#......#...#.....#..................................#..#.#......
|
||||||
|
...##..............#..................#...#......#........###..#.......#..........#..............................#......#..........
|
||||||
|
.#.#.#....#..........#......#.#.........#.....#...............................#.....#.#............#....#........#.............#...
|
||||||
|
........#.........#.........#......................#..#......##.....#..#..........................#......##....#......##.##.....#..
|
||||||
|
.##...#.......#.#....#..#.#...................#.........#....#...........#.....#.........#............##......#............#.......
|
||||||
|
.##..#.........#..........#.#.................................#.#.#...............................#............#......##...#.#.....
|
||||||
|
......#........#..#...#............#..............#............#......##.....#.................................#......#.#.....#....
|
||||||
|
..........#........#...........#....................................#.....#...............................#............##....#.##..
|
||||||
|
........#.............#..#......##..................#.............#..#...#.#.....#...#...............#........................#....
|
||||||
|
....#...............#..........#....#...........................#....##.##...................#.#.......#...#.##....#........##..#..
|
||||||
|
......#.....#..#..........###...#.................####.###..........#...........#..........#......#............................#...
|
||||||
|
.#...#......#........#..#............##...............#.##......#...#.....#....................#.........#............#...#........
|
||||||
|
................##...................#.##..............#...#..#.......#.......###........#..#..#........#...##.....................
|
||||||
|
..............#....#..#..#.............##..............#................................#.....#..#....###.##..............#........
|
||||||
|
..#..............#........................................#..........#.....#..................#............#..#....................
|
||||||
|
.........#...#.....#...#...##...........#.###............##...#........#......................##......#....#.......#...............
|
||||||
|
....#....#.....#.......#......................................#.#.#....#..#..#..........#...................#........#...#.........
|
||||||
|
..#..#..................#..............#...#..#.........#......#....#.#................##..........#..#................#...........
|
||||||
|
...#...................#...........#....#...#.............##...#.......#.#..........#..#...............#....#....#.............#...
|
||||||
|
.......................##.#.#..##........#....#.........#.#.#.....##..............#.......#.......##.#..........#.#................
|
||||||
|
.....#..#..................#..##....#.......#.............#...#.....#.............#.............#.#...............#.....##......##.
|
||||||
|
...#.#.....#..........#.#............#..#..........................##.............#....#.......#.#...#...#....................#.#..
|
||||||
|
............##.#............#....#....#....#..##...#...............................#...#...#.........#.......................##.##.
|
||||||
|
....#.#...............#...#.......#............#..#...........................#..............#..........#....#...#...#..#...#....#.
|
||||||
|
.......#..#..#.#..#......#..........................#...............#.........#...........#................#..#...#................
|
||||||
|
...#..#...#.....#.#.......#....................................................#........#..........#.#...#......#..........#.......
|
||||||
|
..#...#.......#..#..............#.#...#.....#...#....#............#..........##...#.........##.............#.......................
|
||||||
|
...#.............#...#....#...#.....#.#.#..............#..........#........#........##...........#..#.#......................#.....
|
||||||
|
.#.......#.................#...............#..........#.....................#.....#............#......##....#.....#...#....###.....
|
||||||
|
...##...........#..........#.#........#............#..#.#........................#.....##............#...##.#.......#.##....#......
|
||||||
|
...........#........#...........#.......#......#...#.....#............................#........#..#................#...#....##.....
|
||||||
|
...##.##.........#.####..#............#..#.....#.......................#......#..........#.#..#.#....##........#....#.....#..#..##.
|
||||||
|
...................................................................................................................................
|
||||||
99
aoc2023/day21/main.go
Normal file
99
aoc2023/day21/main.go
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
41
aoc2023/day21/main_test.go
Normal file
41
aoc2023/day21/main_test.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
13
aoc2023/day25/example.txt
Normal file
13
aoc2023/day25/example.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
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
|
||||||
1261
aoc2023/day25/input.txt
Normal file
1261
aoc2023/day25/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
63
aoc2023/day25/main.go
Normal file
63
aoc2023/day25/main.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
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++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ func TestExample(t *testing.T) {
|
|||||||
is.NoErr(err)
|
is.NoErr(err)
|
||||||
|
|
||||||
t.Log(result)
|
t.Log(result)
|
||||||
is.Equal(result.valuePT1, 102)
|
is.Equal(result.valuePT1, 50)
|
||||||
is.Equal(result.valuePT2, 0)
|
is.Equal(result.valuePT2, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
6
aoc2024/day01/example.txt
Normal file
6
aoc2024/day01/example.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
3 4
|
||||||
|
4 3
|
||||||
|
2 5
|
||||||
|
1 3
|
||||||
|
3 9
|
||||||
|
3 3
|
||||||
1000
aoc2024/day01/input.txt
Normal file
1000
aoc2024/day01/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
86
aoc2024/day01/main.go
Normal file
86
aoc2024/day01/main.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user