Compare commits
69 Commits
50f1016372
...
day23
| Author | SHA1 | Date | |
|---|---|---|---|
|
0dc039f032
|
|||
|
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
|
|||
| 6a03be9ca9 | |||
|
eb9e770a94
|
|||
|
13888edaff
|
|||
|
7d9d2a7614
|
|||
|
18bf5a4aef
|
|||
|
e742db7ec9
|
|||
|
b97ecdc93c
|
|||
|
a0d852416f
|
|||
|
77a54c5563
|
|||
|
186cfb3157
|
|||
|
142a8dc00f
|
|||
|
6fce822def
|
|||
|
eb758ab41d
|
|||
|
fa2e7fedd9
|
|||
|
927fabebfc
|
|||
|
127e9c33c6
|
|||
| 0204b4841b | |||
| 4159024e6f | |||
|
596f3e7533
|
|||
| aff141a362 | |||
|
30241aa5d3
|
|||
|
cb2b6087b7
|
|||
|
3f5ffa515c
|
|||
| 7826654bce | |||
| a956970738 | |||
| 16a9afb2cb | |||
|
f2d7a9f6b2
|
|||
| 1045fcba4c | |||
| c87eb85e46 | |||
| 055c5b269d | |||
| a7569c8b91 | |||
| 5106558ce9 | |||
| 8e7fa3c5a8 | |||
|
e9068fdf78
|
30
.gitea/workflows/github-mirror.yml
Normal file
30
.gitea/workflows/github-mirror.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Go Bump
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
bump:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Deploy to external repository
|
||||
uses: https://git.sour.is/actions/github-action-push-to-another-repository@main
|
||||
env:
|
||||
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
|
||||
with:
|
||||
# GitHub Action output files
|
||||
source-directory: .
|
||||
destination-github-username: jonlundy
|
||||
destination-repository-name: advent-of-code
|
||||
user-email: jon@xuu.cc
|
||||
# It defaults to `main`
|
||||
target-branch: "main"
|
||||
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
|
||||
33
.gitea/workflows/test.yml
Normal file
33
.gitea/workflows/test.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Go Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
||||
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
|
||||
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
||||
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
ls ${{ gitea.workspace }}
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.21.3
|
||||
|
||||
- name: Test
|
||||
run: go test -timeout 240s -race -cover ./...
|
||||
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
280
aoc_test.go
Normal file
280
aoc_test.go
Normal file
@@ -0,0 +1,280 @@
|
||||
package aoc_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/matryer/is"
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
lis := aoc.NewList[int](nil)
|
||||
lis.Add(5, 0)
|
||||
|
||||
a, _ := lis.Head().Value()
|
||||
|
||||
is.Equal(a, 5)
|
||||
}
|
||||
|
||||
func TestPriorityQueue(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
type elem [2]int
|
||||
less := func(b, a *elem) bool {
|
||||
return (*a)[0] < (*b)[0]
|
||||
}
|
||||
|
||||
pq := aoc.PriorityQueue(less)
|
||||
|
||||
pq.Insert(&elem{1, 4})
|
||||
pq.Insert(&elem{3, 2})
|
||||
pq.Insert(&elem{2, 3})
|
||||
pq.Insert(&elem{4, 1})
|
||||
|
||||
v := pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{4, 1})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{3, 2})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{2, 3})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{1, 4})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v == nil)
|
||||
}
|
||||
|
||||
|
||||
func ExamplePriorityQueue() {
|
||||
type memo struct {
|
||||
pt int
|
||||
score int
|
||||
}
|
||||
less := func(a, b *memo) bool { return a.score < b.score }
|
||||
|
||||
adj := map[int][][2]int{
|
||||
0: {{1, 2}, {2, 6}},
|
||||
1: {{3, 5}},
|
||||
2: {{3, 8}},
|
||||
3: {{4, 10}, {5, 15}},
|
||||
4: {{6, 2}},
|
||||
5: {{6, 6}},
|
||||
}
|
||||
|
||||
pq := aoc.PriorityQueue(less)
|
||||
visited := aoc.Set([]int{}...)
|
||||
dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
|
||||
|
||||
dist.Set(0, 0)
|
||||
pq.Insert(&memo{0, 0})
|
||||
|
||||
for !pq.IsEmpty() {
|
||||
m := pq.ExtractMin()
|
||||
|
||||
u := m.pt
|
||||
if visited.Has(u) {
|
||||
continue
|
||||
}
|
||||
visited.Add(u)
|
||||
|
||||
du, _ := dist.Get(u)
|
||||
|
||||
for _, edge := range adj[u] {
|
||||
v, w := edge[0], edge[1]
|
||||
dv, _ := dist.Get(v)
|
||||
|
||||
if !visited.Has(v) && du+w < dv {
|
||||
dist.Set(v, du+w)
|
||||
pq.Insert(&memo{v, du + w})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items := dist.Items()
|
||||
sort.Slice(items, func(i, j int) bool { return items[i].K < items[j].K })
|
||||
for _, v := range items {
|
||||
fmt.Printf("point %d is %d steps away.\n", v.K, v.V)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// point 0 is 0 steps away.
|
||||
// point 1 is 2 steps away.
|
||||
// point 2 is 6 steps away.
|
||||
// point 3 is 7 steps away.
|
||||
// point 4 is 17 steps away.
|
||||
// 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 {
|
||||
pt int
|
||||
score int
|
||||
}
|
||||
less := func(a, b *memo) bool { return (*a).score < (*b).score }
|
||||
|
||||
adj := map[int][][2]int{
|
||||
0: {{1, 2}, {2, 6}},
|
||||
1: {{3, 5}},
|
||||
2: {{3, 8}},
|
||||
3: {{4, 10}, {5, 15}},
|
||||
4: {{6, 2}},
|
||||
5: {{6, 6}},
|
||||
}
|
||||
|
||||
pq := aoc.FibHeap(less)
|
||||
visited := aoc.Set([]int{}...)
|
||||
dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
|
||||
|
||||
dist.Set(0, 0)
|
||||
pq.Insert(&memo{0, 0})
|
||||
|
||||
for !pq.IsEmpty() {
|
||||
m := pq.ExtractMin()
|
||||
|
||||
u := m.pt
|
||||
if visited.Has(u) {
|
||||
continue
|
||||
}
|
||||
visited.Add(u)
|
||||
|
||||
du, _ := dist.Get(u)
|
||||
|
||||
for _, edge := range adj[u] {
|
||||
v, w := edge[0], edge[1]
|
||||
dv, _ := dist.Get(v)
|
||||
|
||||
if !visited.Has(v) && du+w < dv {
|
||||
dist.Set(v, du+w)
|
||||
pq.Insert(&memo{v, du + w})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items := dist.Items()
|
||||
sort.Slice(items, func(i, j int) bool { return items[i].K < items[j].K })
|
||||
for _, v := range items {
|
||||
fmt.Printf("point %d is %d steps away.\n", v.K, v.V)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// point 0 is 0 steps away.
|
||||
// point 1 is 2 steps away.
|
||||
// point 2 is 6 steps away.
|
||||
// point 3 is 7 steps away.
|
||||
// point 4 is 17 steps away.
|
||||
// point 5 is 22 steps away.
|
||||
// point 6 is 19 steps away.
|
||||
}
|
||||
|
||||
func TestFibHeap(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
type elem [2]int
|
||||
less := func(a, b *elem) bool {
|
||||
return (*a)[0] < (*b)[0]
|
||||
}
|
||||
|
||||
pq := aoc.FibHeap(less)
|
||||
|
||||
pq.Insert(&elem{1, 4})
|
||||
pq.Insert(&elem{3, 2})
|
||||
pq.Insert(&elem{2, 3})
|
||||
pq.Insert(&elem{4, 1})
|
||||
|
||||
v := pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{1, 4})
|
||||
|
||||
pq.Insert(&elem{5, 8})
|
||||
pq.Insert(&elem{6, 7})
|
||||
pq.Insert(&elem{7, 6})
|
||||
pq.Insert(&elem{8, 5})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{2, 3})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{3, 2})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{4, 1})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{5, 8})
|
||||
|
||||
m := aoc.FibHeap(less)
|
||||
m.Insert(&elem{1, 99})
|
||||
m.Insert(&elem{12, 9})
|
||||
m.Insert(&elem{11, 10})
|
||||
m.Insert(&elem{10, 11})
|
||||
m.Insert(&elem{9, 12})
|
||||
|
||||
pq.Merge(m)
|
||||
|
||||
v = pq.Find(func(t *elem) bool {
|
||||
return (*t)[0] == 6
|
||||
})
|
||||
is.Equal(v, &elem{6, 7})
|
||||
|
||||
v = pq.Find(func(t *elem) bool {
|
||||
return (*t)[0] == 12
|
||||
})
|
||||
is.Equal(v, &elem{12, 9})
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{1, 99})
|
||||
|
||||
pq.DecreaseKey(
|
||||
func(t *elem) bool { return t[0] == 12 },
|
||||
func(t *elem) { t[0] = 3 },
|
||||
)
|
||||
|
||||
v = pq.ExtractMin()
|
||||
is.True(v != nil)
|
||||
is.Equal(v, &elem{3, 9})
|
||||
|
||||
var keys []int
|
||||
for !pq.IsEmpty() {
|
||||
v := pq.ExtractMin()
|
||||
fmt.Println(v)
|
||||
keys = append(keys, v[0])
|
||||
}
|
||||
is.Equal(keys, []int{6, 7, 8, 9, 10, 11})
|
||||
}
|
||||
4
day01/example1.txt
Normal file
4
day01/example1.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
1abc2
|
||||
pqr3stu8vwx
|
||||
a1b2c3d4e5f
|
||||
treb7uchet
|
||||
7
day01/example2.txt
Normal file
7
day01/example2.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
two1nine
|
||||
eightwothree
|
||||
abcone2threexyz
|
||||
xtwone3four
|
||||
4nineeightseven2
|
||||
zoneight234
|
||||
7pqrstsixteen
|
||||
151
day01/main.go
151
day01/main.go
@@ -2,25 +2,32 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
//go:embed input.txt
|
||||
var input []byte
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
func main() {
|
||||
buf := bytes.NewReader(input)
|
||||
scan := bufio.NewScanner(buf)
|
||||
type result struct {
|
||||
sum int
|
||||
sum2 int
|
||||
}
|
||||
|
||||
func (r result) String() string {
|
||||
return fmt.Sprintln("result pt1:", r.sum, "\nresult pt2:", r.sum2)
|
||||
}
|
||||
|
||||
var numbers = []string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}
|
||||
|
||||
func run(scan *bufio.Scanner) (*result, error) {
|
||||
result := &result{}
|
||||
|
||||
sum := 0
|
||||
for scan.Scan() {
|
||||
var first, last int
|
||||
|
||||
orig := scan.Text()
|
||||
_ = orig
|
||||
var first2, last2 int
|
||||
|
||||
text := scan.Text()
|
||||
|
||||
@@ -30,110 +37,66 @@ func main() {
|
||||
|
||||
switch {
|
||||
case slice[0] >= '0' && slice[0] <= '9':
|
||||
first = int(slice[0] - '0')
|
||||
case strings.HasPrefix(string(slice), "one"):
|
||||
first = 1
|
||||
case strings.HasPrefix(string(slice), "two"):
|
||||
first = 2
|
||||
case strings.HasPrefix(string(slice), "three"):
|
||||
first = 3
|
||||
case strings.HasPrefix(string(slice), "four"):
|
||||
first = 4
|
||||
case strings.HasPrefix(string(slice), "five"):
|
||||
first = 5
|
||||
case strings.HasPrefix(string(slice), "six"):
|
||||
first = 6
|
||||
case strings.HasPrefix(string(slice), "seven"):
|
||||
first = 7
|
||||
case strings.HasPrefix(string(slice), "eight"):
|
||||
first = 8
|
||||
case strings.HasPrefix(string(slice), "nine"):
|
||||
first = 9
|
||||
if first == 0 {
|
||||
first = int(slice[0] - '0')
|
||||
}
|
||||
if first2 == 0 {
|
||||
first2 = int(slice[0] - '0')
|
||||
}
|
||||
default:
|
||||
if first2 != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for i, s := range numbers {
|
||||
if strings.HasPrefix(string(slice), s) {
|
||||
first2 = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if first != 0 {
|
||||
if first != 0 && first2 != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
text = string(reverse([]rune(text)))
|
||||
text = string(aoc.Reverse([]rune(text)))
|
||||
|
||||
for i := range text {
|
||||
copy(slice, []rune(text[i:]))
|
||||
slice = reverse(slice)
|
||||
slice = aoc.Reverse(slice)
|
||||
|
||||
switch {
|
||||
case slice[4] >= '0' && slice[4] <= '9':
|
||||
last = int(slice[4] - '0')
|
||||
case strings.HasSuffix(string(slice), "one"):
|
||||
last = 1
|
||||
case strings.HasSuffix(string(slice), "two"):
|
||||
last = 2
|
||||
case strings.HasSuffix(string(slice), "three"):
|
||||
last = 3
|
||||
case strings.HasSuffix(string(slice), "four"):
|
||||
last = 4
|
||||
case strings.HasSuffix(string(slice), "five"):
|
||||
last = 5
|
||||
case strings.HasSuffix(string(slice), "six"):
|
||||
last = 6
|
||||
case strings.HasSuffix(string(slice), "seven"):
|
||||
last = 7
|
||||
case strings.HasSuffix(string(slice), "eight"):
|
||||
last = 8
|
||||
case strings.HasSuffix(string(slice), "nine"):
|
||||
last = 9
|
||||
if last == 0 {
|
||||
last = int(slice[4] - '0')
|
||||
}
|
||||
if last2 == 0 {
|
||||
last2 = int(slice[4] - '0')
|
||||
}
|
||||
default:
|
||||
if last2 != 0 {
|
||||
continue
|
||||
}
|
||||
for i, s := range numbers {
|
||||
if strings.HasSuffix(string(slice), s) {
|
||||
last2 = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if last != 0 {
|
||||
if last != 0 && last2 != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
sum += first*10 + last
|
||||
result.sum += first*10 + last
|
||||
result.sum2 += first2*10 + last2
|
||||
}
|
||||
if err := scan.Err(); err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println(sum)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func reverse[T any](arr []T) []T{
|
||||
for i := 0; i < len(arr)/2; i++ {
|
||||
arr[i], arr[len(arr)-i-1] = arr[len(arr)-i-1], arr[i]
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
|
||||
// type sorter[T rune | int] []T
|
||||
|
||||
// func (s sorter[T]) Less(i, j int) bool { return s[i] < s[j] }
|
||||
// func (s sorter[T]) Len() int { return len(s) }
|
||||
// func (s sorter[T]) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
/*
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
one
|
||||
two
|
||||
three
|
||||
four
|
||||
five
|
||||
six
|
||||
seven
|
||||
eight
|
||||
nine
|
||||
ten
|
||||
|
||||
|
||||
*/
|
||||
|
||||
53
day01/main_test.go
Normal file
53
day01/main_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
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.sum, 142)
|
||||
}
|
||||
|
||||
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.sum2, 281)
|
||||
}
|
||||
func TestInput(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.sum, 54573)
|
||||
is.Equal(result.sum2, 54591)
|
||||
}
|
||||
@@ -2,24 +2,39 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
//go:embed input.txt
|
||||
var input []byte
|
||||
func main() {
|
||||
result, err := aoc.Runner(run)
|
||||
if err != nil {
|
||||
aoc.Log("ERR", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
aoc.Log(result)
|
||||
}
|
||||
|
||||
type result struct {
|
||||
sum int
|
||||
powerSum int
|
||||
}
|
||||
|
||||
func (r result) String() string {
|
||||
return fmt.Sprintln("result pt1:", r.sum, "\nresult pt2:", r.powerSum)
|
||||
}
|
||||
|
||||
type gameResult struct {
|
||||
red, green, blue int
|
||||
}
|
||||
|
||||
func main() {
|
||||
buf := bytes.NewReader(input)
|
||||
scan := bufio.NewScanner(buf)
|
||||
|
||||
func run(scan *bufio.Scanner) (*result, error) {
|
||||
// only 12 red cubes, 13 green cubes, and 14 blue cubes
|
||||
maxCounts := gameResult{
|
||||
red: 12,
|
||||
@@ -36,12 +51,10 @@ func main() {
|
||||
continue
|
||||
}
|
||||
|
||||
games = append(games, []gameResult{})
|
||||
rounds := aoc.SliceMap(func(text string) gameResult {
|
||||
round := gameResult{}
|
||||
|
||||
for _, round := range strings.Split(text, ";") {
|
||||
game := gameResult{}
|
||||
|
||||
for _, result := range strings.Split(round, ",") {
|
||||
for _, result := range strings.Split(text, ",") {
|
||||
ns, color, _ := strings.Cut(strings.TrimSpace(result), " ")
|
||||
n, err := strconv.Atoi(ns)
|
||||
if err != nil {
|
||||
@@ -50,20 +63,21 @@ func main() {
|
||||
|
||||
switch color {
|
||||
case "red":
|
||||
game.red = n
|
||||
round.red = n
|
||||
case "green":
|
||||
game.green = n
|
||||
round.green = n
|
||||
case "blue":
|
||||
game.blue = n
|
||||
round.blue = n
|
||||
}
|
||||
|
||||
}
|
||||
games[len(games)-1] = append(games[len(games)-1], game)
|
||||
}
|
||||
return round
|
||||
}, strings.Split(text, ";")...)
|
||||
|
||||
games = append(games, rounds)
|
||||
}
|
||||
|
||||
fmt.Println(games)
|
||||
fmt.Println(len(games))
|
||||
aoc.Log(games)
|
||||
aoc.Log(len(games))
|
||||
|
||||
sum := 0
|
||||
powerSum := 0
|
||||
@@ -81,24 +95,24 @@ func main() {
|
||||
mins.blue = max(mins.blue, round.blue)
|
||||
|
||||
if maxCounts.red < round.red {
|
||||
fmt.Println("game", i, round, "too many red", round.red)
|
||||
aoc.Log("game", i, round, "too many red", round.red)
|
||||
ok = false
|
||||
} else if maxCounts.blue < round.blue {
|
||||
fmt.Println("game", i, round, "too many blue", round.blue)
|
||||
aoc.Log("game", i, round, "too many blue", round.blue)
|
||||
ok = false
|
||||
} else if maxCounts.green < round.green {
|
||||
fmt.Println("game", i, round, "too many green", round.green)
|
||||
aoc.Log("game", i, round, "too many green", round.green)
|
||||
ok = false
|
||||
}
|
||||
fmt.Println("game", i, round, ok)
|
||||
aoc.Log("game", i, round, ok)
|
||||
}
|
||||
if ok {
|
||||
sum += i
|
||||
fmt.Println("game", i, "passes", sum)
|
||||
aoc.Log("game", i, "passes", sum)
|
||||
}
|
||||
power := mins.red*mins.blue*mins.green
|
||||
fmt.Println("game", i, "mins", mins, power)
|
||||
power := mins.red * mins.blue * mins.green
|
||||
aoc.Log("game", i, "mins", mins, power)
|
||||
powerSum += power
|
||||
}
|
||||
fmt.Println("sum", sum, "power", powerSum)
|
||||
return &result{sum, powerSum}, nil
|
||||
}
|
||||
|
||||
41
day02/main_test.go
Normal file
41
day02/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.sum, 8)
|
||||
is.Equal(result.powerSum, 2286)
|
||||
}
|
||||
|
||||
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.sum, 2317)
|
||||
is.Equal(result.powerSum, 74804)
|
||||
}
|
||||
@@ -2,14 +2,14 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
//go:embed input.txt
|
||||
var input []byte
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
type partNumber struct {
|
||||
number int
|
||||
@@ -56,10 +56,12 @@ func (tab symbolTab) scanSymbol(p partNumber) bool {
|
||||
// 553079
|
||||
// 84363105
|
||||
|
||||
func main() {
|
||||
buf := bytes.NewReader(input)
|
||||
scan := bufio.NewScanner(buf)
|
||||
type result struct {
|
||||
valuePT1 int
|
||||
valuePT2 int
|
||||
}
|
||||
|
||||
func run(scan *bufio.Scanner) (*result, error) {
|
||||
parts := []partNumber{}
|
||||
symbols := make(symbolTab)
|
||||
symbolList := []*symbol{}
|
||||
@@ -95,28 +97,32 @@ func main() {
|
||||
if v, err := strconv.Atoi(string(slice)); err == nil {
|
||||
parts = append(parts, partNumber{number: v, row: row, col: col - len(slice), end: col - 1})
|
||||
slice = slice[:0]
|
||||
_ = slice
|
||||
}
|
||||
}
|
||||
|
||||
sum := 0
|
||||
for i, p := range parts {
|
||||
ok := symbols.scanSymbol(p)
|
||||
parts[i].hasSymbol = ok
|
||||
if ok {
|
||||
sum += p.number
|
||||
}
|
||||
}
|
||||
sum := aoc.SumIFunc(
|
||||
func(i int, p partNumber) int {
|
||||
ok := symbols.scanSymbol(p)
|
||||
parts[i].hasSymbol = ok
|
||||
if ok {
|
||||
return p.number
|
||||
}
|
||||
return 0
|
||||
}, parts...)
|
||||
|
||||
sumGears := 0
|
||||
for _, s := range symbolList {
|
||||
if s.symbol == '*' && len(s.adjacentParts) == 2 {
|
||||
sumGears += s.adjacentParts[0].number * s.adjacentParts[1].number
|
||||
}
|
||||
}
|
||||
sumGears := aoc.SumFunc(
|
||||
func(s *symbol) int {
|
||||
if s.symbol == '*' && len(s.adjacentParts) == 2 {
|
||||
return s.adjacentParts[0].number * s.adjacentParts[1].number
|
||||
}
|
||||
return 0
|
||||
}, symbolList...)
|
||||
|
||||
// fmt.Println(parts)
|
||||
// fmt.Println(symbols)
|
||||
// fmt.Println(symbolList)
|
||||
fmt.Println("part1:", sum)
|
||||
fmt.Println("part2:", sumGears)
|
||||
return &result{sum, sumGears}, nil
|
||||
}
|
||||
|
||||
43
day03/main_test.go
Normal file
43
day03/main_test.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"testing"
|
||||
|
||||
"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, int(4361))
|
||||
|
||||
is.Equal(result.valuePT2, 467835)
|
||||
}
|
||||
|
||||
func TestInput(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
t.Log(result.valuePT1)
|
||||
is.Equal(result.valuePT1, int(553079))
|
||||
|
||||
t.Log(result.valuePT2)
|
||||
is.Equal(result.valuePT2, 84363105)
|
||||
}
|
||||
@@ -2,13 +2,12 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
//go:embed input.txt
|
||||
@@ -21,22 +20,14 @@ type card struct {
|
||||
copies int
|
||||
}
|
||||
|
||||
func main() {
|
||||
var level slog.Level
|
||||
if err := level.UnmarshalText([]byte(os.Getenv("DEBUG_LEVEL"))); err == nil && level != 0 {
|
||||
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: level})))
|
||||
}
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
buf := bytes.NewReader(input)
|
||||
scan := bufio.NewScanner(buf)
|
||||
|
||||
points, cards := run(scan)
|
||||
|
||||
fmt.Println("points:", points)
|
||||
fmt.Println("cards:", cards)
|
||||
type result struct {
|
||||
points int
|
||||
cards int
|
||||
}
|
||||
|
||||
func run(scan *bufio.Scanner) (int, int) {
|
||||
func run(scan *bufio.Scanner) (result, error) {
|
||||
cards := []*card{}
|
||||
|
||||
for scan.Scan() {
|
||||
@@ -46,7 +37,7 @@ func run(scan *bufio.Scanner) (int, int) {
|
||||
continue
|
||||
}
|
||||
|
||||
num, _ := strconv.Atoi(strings.TrimSpace(strings.SplitN(pfx, " ", 2)[1]))
|
||||
num := aoc.Atoi(strings.TrimSpace(strings.SplitN(pfx, " ", 2)[1]))
|
||||
cards = append(cards, &card{card: num})
|
||||
buf := make([]rune, 0, 4)
|
||||
winner := true
|
||||
@@ -71,7 +62,7 @@ func run(scan *bufio.Scanner) (int, int) {
|
||||
}
|
||||
|
||||
if len(buf) > 0 {
|
||||
num, _ = strconv.Atoi(string(buf))
|
||||
num = aoc.Atoi(string(buf))
|
||||
buf = buf[:0]
|
||||
_ = buf // ignore
|
||||
cards[len(cards)-1].scratch = append(cards[len(cards)-1].scratch, num)
|
||||
@@ -105,5 +96,5 @@ func run(scan *bufio.Scanner) (int, int) {
|
||||
slog.Debug("points", "card", card.card, "match", m, "score", sumPoints)
|
||||
}
|
||||
|
||||
return sumPoints, sumCards
|
||||
return result{sumPoints, sumCards}, nil
|
||||
}
|
||||
|
||||
@@ -17,16 +17,18 @@ func TestExample(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(example))
|
||||
|
||||
points, cards := run(scan)
|
||||
is.Equal(points, 13)
|
||||
is.Equal(cards, 30)
|
||||
r, err := run(scan)
|
||||
is.NoErr(err)
|
||||
is.Equal(r.points, 13)
|
||||
is.Equal(r.cards, 30)
|
||||
}
|
||||
|
||||
func TestSolution(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
points, cards := run(scan)
|
||||
is.Equal(points, 23235)
|
||||
is.Equal(cards, 5920640)
|
||||
r, err := run(scan)
|
||||
is.NoErr(err)
|
||||
is.Equal(r.points, 23235)
|
||||
is.Equal(r.cards, 5920640)
|
||||
}
|
||||
|
||||
@@ -7,27 +7,18 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprintln(os.Stderr, "Usage: day05 FILE")
|
||||
}
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
input, err := os.Open(os.Args[1])
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
|
||||
scan := bufio.NewScanner(input)
|
||||
|
||||
minLocation, minRangeLocation := run(scan)
|
||||
|
||||
fmt.Println("min location:", minLocation)
|
||||
fmt.Println("min range location:", minRangeLocation)
|
||||
type result struct {
|
||||
minLocation int
|
||||
minRange int
|
||||
}
|
||||
|
||||
func run(scan *bufio.Scanner) (int, int) {
|
||||
func run(scan *bufio.Scanner) (result, error) {
|
||||
log("begin...")
|
||||
|
||||
var seeds []int
|
||||
@@ -55,15 +46,14 @@ func run(scan *bufio.Scanner) (int, int) {
|
||||
lookup["humidity-to-location"],
|
||||
)
|
||||
|
||||
return findMinLocation(seeds, find), FindMinRangeLocationMulti(seedRanges, find)
|
||||
return result{findMinLocation(seeds, find), FindMinRangeLocationMulti(seedRanges, find)}, nil
|
||||
}
|
||||
|
||||
func readSeeds(text string) ([]int, [][2]int) {
|
||||
var seeds [] int
|
||||
var seeds []int
|
||||
var seedRanges [][2]int
|
||||
sp := strings.Fields(strings.TrimPrefix(text, "seeds: "))
|
||||
for i, s := range sp {
|
||||
n, _ := strconv.Atoi(s)
|
||||
|
||||
for i, n := range aoc.SliceMap(aoc.Atoi, strings.Fields(strings.TrimPrefix(text, "seeds: "))...) {
|
||||
seeds = append(seeds, n)
|
||||
|
||||
if i%2 == 0 {
|
||||
@@ -121,7 +111,7 @@ func FindMinRangeLocation(ranges [][2]int, find *Finder) int {
|
||||
|
||||
for _, s := range ranges {
|
||||
for i := 0; i < s[1]; i++ {
|
||||
seedLocations = append(seedLocations, find.Find(s[0] + i))
|
||||
seedLocations = append(seedLocations, find.Find(s[0]+i))
|
||||
}
|
||||
}
|
||||
return min(seedLocations...)
|
||||
@@ -164,7 +154,7 @@ func FindMinRangeLocationMulti(ranges [][2]int, find *Finder) int {
|
||||
seedLocations := make([]int, 0, results)
|
||||
expectResults := make([]struct{}, len(ranges))
|
||||
for range expectResults {
|
||||
r := <- resultsCh
|
||||
r := <-resultsCh
|
||||
seedLocations = append(seedLocations, r...)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,19 +20,20 @@ func TestExample(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(example))
|
||||
|
||||
minLocation, minRangeLocation := run(scan)
|
||||
is.Equal(minLocation, 35)
|
||||
is.Equal(minRangeLocation, 46)
|
||||
r, err := run(scan)
|
||||
is.NoErr(err)
|
||||
is.Equal(r.minLocation, 35)
|
||||
is.Equal(r.minRange, 46)
|
||||
}
|
||||
|
||||
func SkipTestSolution(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
minLocation, minRangeLocation := run(scan)
|
||||
is.Equal(minLocation, 199602917)
|
||||
is.Equal(minRangeLocation, 0)
|
||||
|
||||
r, err := run(scan)
|
||||
is.NoErr(err)
|
||||
is.Equal(r.minLocation, 199602917)
|
||||
is.Equal(r.minRange, 2254686)
|
||||
}
|
||||
|
||||
func TestLookup(t *testing.T) {
|
||||
@@ -44,9 +45,9 @@ func TestLookup(t *testing.T) {
|
||||
is.Equal(find.Find(79), 81)
|
||||
|
||||
find = &Lookup{ranges: Ranges{
|
||||
{77,45,23},
|
||||
{45,81,19},
|
||||
{64,68,13},
|
||||
{77, 45, 23},
|
||||
{45, 81, 19},
|
||||
{64, 68, 13},
|
||||
}}
|
||||
is.Equal(find.Find(77), 45)
|
||||
|
||||
@@ -62,38 +63,38 @@ func TestFinder(t *testing.T) {
|
||||
}},
|
||||
// soil-to-fertilizer
|
||||
&Lookup{ranges: Ranges{
|
||||
{15, 0,37},
|
||||
{52,37,2},
|
||||
{0,39,15},
|
||||
{15, 0, 37},
|
||||
{52, 37, 2},
|
||||
{0, 39, 15},
|
||||
}},
|
||||
// fertilizer-to-water
|
||||
&Lookup{ranges: Ranges{
|
||||
{53,49,8},
|
||||
{11,0,42},
|
||||
{0,42,7},
|
||||
{7,57,4},
|
||||
{53, 49, 8},
|
||||
{11, 0, 42},
|
||||
{0, 42, 7},
|
||||
{7, 57, 4},
|
||||
}},
|
||||
// water-to-light
|
||||
&Lookup{ranges: Ranges{
|
||||
{18,88,7},
|
||||
{25,18,70},
|
||||
{18, 88, 7},
|
||||
{25, 18, 70},
|
||||
}},
|
||||
// light-to-temperature
|
||||
&Lookup{ranges: Ranges{
|
||||
{77,45,23},
|
||||
{45,81,19},
|
||||
{64,68,13},
|
||||
{77, 45, 23},
|
||||
{45, 81, 19},
|
||||
{64, 68, 13},
|
||||
}},
|
||||
// temperature-to-humidity
|
||||
&Lookup{ranges: Ranges{
|
||||
{69,0,1},
|
||||
{0,1,69},
|
||||
{69, 0, 1},
|
||||
{0, 1, 69},
|
||||
}},
|
||||
// humidity-to-location
|
||||
&Lookup{ranges: Ranges{
|
||||
{56,60,37},
|
||||
{93,56,4},
|
||||
{56, 60, 37},
|
||||
{93, 56, 4},
|
||||
}},
|
||||
)
|
||||
is.Equal(find.Find(82), 46)
|
||||
}
|
||||
}
|
||||
|
||||
172
day07/main.go
172
day07/main.go
@@ -3,30 +3,20 @@ package main
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprintln(os.Stderr, "Usage: day07 FILE")
|
||||
}
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
input, err := os.Open(os.Args[1])
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
|
||||
scan := bufio.NewScanner(input)
|
||||
|
||||
score1, score2 := run(scan)
|
||||
|
||||
fmt.Println("score 1", score1)
|
||||
fmt.Println("score 2", score2)
|
||||
type result struct {
|
||||
valuePT1 uint64
|
||||
valuePT2 uint64
|
||||
}
|
||||
|
||||
func run(scan *bufio.Scanner) (uint64, uint64) {
|
||||
var game1, game2 Game
|
||||
func run(scan *bufio.Scanner) (result, error) {
|
||||
var game Game
|
||||
|
||||
for scan.Scan() {
|
||||
var cards string
|
||||
@@ -37,26 +27,23 @@ func run(scan *bufio.Scanner) (uint64, uint64) {
|
||||
}
|
||||
|
||||
fmt.Println("cards", cards, "bid", bid)
|
||||
game1.Append(cards, bid)
|
||||
game2.Append(cards, bid)
|
||||
game.plays = append(game.plays, Play{bid, []rune(cards), &game})
|
||||
}
|
||||
|
||||
game1.cardTypes = cardTypes1
|
||||
game1.cardOrder = getOrder(cardTypes1)
|
||||
product1 := calcProduct(game1)
|
||||
game.cardOrder = getOrder(cardTypes1)
|
||||
product1 := calcProduct(game)
|
||||
|
||||
game2.cardTypes = cardTypes2
|
||||
game2.cardOrder = getOrder(cardTypes2)
|
||||
game2.wildCard = 'J'
|
||||
product2 := calcProduct(game2)
|
||||
game.cardOrder = getOrder(cardTypes2)
|
||||
game.wildCard = 'J'
|
||||
product2 := calcProduct(game)
|
||||
|
||||
return product1, product2
|
||||
return result{product1, product2}, nil
|
||||
}
|
||||
|
||||
var cardTypes1 = []rune{'A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2'}
|
||||
var cardTypes2 = []rune{'A', 'K', 'Q', 'T', '9', '8', '7', '6', '5', '4', '3', '2', 'J'}
|
||||
|
||||
func calcProduct(game Game) uint64 {
|
||||
func calcProduct(game Game) uint64 {
|
||||
sort.Sort(game.plays)
|
||||
|
||||
var product uint64
|
||||
@@ -79,108 +66,92 @@ func getOrder(cardTypes []rune) map[rune]int {
|
||||
type Game struct {
|
||||
plays Plays
|
||||
cardOrder map[rune]int
|
||||
|
||||
cardTypes []rune
|
||||
wildCard rune
|
||||
}
|
||||
|
||||
func (g *Game) Append(cards string, bid int) {
|
||||
p := Play{bid: bid, hand: []rune(cards), game: g}
|
||||
g.plays = append(g.plays, p)
|
||||
}
|
||||
|
||||
type Play struct {
|
||||
bid int
|
||||
hand Hand
|
||||
cardCounts map[rune]int
|
||||
strength int
|
||||
|
||||
game *Game
|
||||
}
|
||||
|
||||
type Hand []rune
|
||||
|
||||
func (h *Play) HandType() string {
|
||||
hs := h.HandStrength()
|
||||
kind := hs& 0xf00000
|
||||
hc := h.game.cardTypes[13-hs&0xf0000>>16]
|
||||
switch kind {
|
||||
case 0x700000:
|
||||
func (h Play) HandType() string {
|
||||
hc, _ := h.HighCard()
|
||||
switch {
|
||||
case h.IsFiveOfKind():
|
||||
return "5K-" + string(hc)
|
||||
case 0x600000:
|
||||
case h.IsFourOfKind():
|
||||
return "4K-" + string(hc)
|
||||
case 0x500000:
|
||||
case h.IsFullHouse():
|
||||
return "FH-" + string(hc)
|
||||
case 0x400000:
|
||||
case h.IsThreeOfKind():
|
||||
return "3K-" + string(hc)
|
||||
case 0x300000:
|
||||
case h.IsTwoPair():
|
||||
return "2P-" + string(hc)
|
||||
case 0x200000:
|
||||
case h.IsOnePair():
|
||||
return "1P-" + string(hc)
|
||||
case 0x100000:
|
||||
case h.IsHighCard():
|
||||
return "HC-" + string(hc)
|
||||
}
|
||||
return "Uno"
|
||||
}
|
||||
|
||||
func (p *Play) HandStrength() int {
|
||||
_, v := p.HighCard()
|
||||
|
||||
func (h Play) HandStrength() int {
|
||||
_, v := h.HighCard()
|
||||
switch {
|
||||
case p.IsFiveOfKind():
|
||||
p.strength = 0x700000 | v
|
||||
case p.IsFourOfKind():
|
||||
p.strength = 0x600000 | v
|
||||
case p.IsFullHouse():
|
||||
p.strength = 0x500000 | v
|
||||
case p.IsThreeOfKind():
|
||||
p.strength = 0x400000 | v
|
||||
case p.IsTwoPair():
|
||||
p.strength = 0x300000 | v
|
||||
case p.IsOnePair():
|
||||
p.strength = 0x200000 | v
|
||||
case p.IsHighCard():
|
||||
p.strength = 0x100000 | v
|
||||
case h.IsFiveOfKind():
|
||||
return 0x700000 | v
|
||||
case h.IsFourOfKind():
|
||||
return 0x600000 | v
|
||||
case h.IsFullHouse():
|
||||
return 0x500000 | v
|
||||
case h.IsThreeOfKind():
|
||||
return 0x400000 | v
|
||||
case h.IsTwoPair():
|
||||
return 0x300000 | v
|
||||
case h.IsOnePair():
|
||||
return 0x200000 | v
|
||||
case h.IsHighCard():
|
||||
return 0x100000 | v
|
||||
}
|
||||
return p.strength
|
||||
return 0
|
||||
}
|
||||
|
||||
func (h Play) IsFiveOfKind() bool {
|
||||
_, _, _, _, has5 := h.game.hasSame(h.cardCounts)
|
||||
_, _, _, _, has5 := h.game.hasSame(h.hand)
|
||||
return has5
|
||||
}
|
||||
func (h Play) IsFourOfKind() bool {
|
||||
_, _, _, has4, _ := h.game.hasSame(h.cardCounts)
|
||||
_, _, _, has4, _ := h.game.hasSame(h.hand)
|
||||
return has4
|
||||
}
|
||||
func (h Play) IsFullHouse() bool {
|
||||
_, has2, has3, _, _ := h.game.hasSame(h.cardCounts)
|
||||
_, has2, has3, _, _ := h.game.hasSame(h.hand)
|
||||
return has3 && has2
|
||||
}
|
||||
func (h Play) IsThreeOfKind() bool {
|
||||
has1, _, has3, _, _ := h.game.hasSame(h.cardCounts)
|
||||
has1, _, has3, _, _ := h.game.hasSame(h.hand)
|
||||
return has3 && has1
|
||||
}
|
||||
func (h Play) IsTwoPair() bool {
|
||||
_, has2, has3, _, _ := h.game.hasSame(h.cardCounts)
|
||||
return !has3 && has2 && h.game.pairs(h.cardCounts) == 2
|
||||
_, has2, has3, _, _ := h.game.hasSame(h.hand)
|
||||
return !has3 && has2 && h.game.pairs(h.hand) == 2
|
||||
}
|
||||
func (h Play) IsOnePair() bool {
|
||||
_, has2, has3, _, _ := h.game.hasSame(h.cardCounts)
|
||||
return !has3 && has2 && h.game.pairs(h.cardCounts) == 1
|
||||
_, has2, has3, _, _ := h.game.hasSame(h.hand)
|
||||
return !has3 && has2 && h.game.pairs(h.hand) == 1
|
||||
}
|
||||
func (h Play) IsHighCard() bool {
|
||||
has1, has2, has3, has4, _ := h.game.hasSame(h.cardCounts)
|
||||
has1, has2, has3, has4, _ := h.game.hasSame(h.hand)
|
||||
return has1 && !has2 && !has3 && !has4
|
||||
}
|
||||
func (h *Play) HighCard() (rune, int) {
|
||||
if h.cardCounts == nil {
|
||||
h.generateCounts()
|
||||
}
|
||||
|
||||
func (h Play) HighCard() (rune, int) {
|
||||
var i int
|
||||
pairs := make(Pairs, 5)
|
||||
for r, c := range h.cardCounts {
|
||||
cnt := h.game.Counts(h.hand)
|
||||
for r, c := range cnt {
|
||||
pairs[i].c = c
|
||||
pairs[i].r = r
|
||||
pairs[i].o = h.game.cardOrder[r]
|
||||
@@ -223,32 +194,29 @@ func (p Plays) Len() int { return len(p) }
|
||||
func (p Plays) Less(i, j int) bool { return p[i].HandStrength() < p[j].HandStrength() }
|
||||
func (p Plays) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
func (p *Play) generateCounts() {
|
||||
cardOrder := p.game.cardOrder
|
||||
wildCard := p.game.wildCard
|
||||
|
||||
p.cardCounts = make(map[rune]int, len(cardOrder))
|
||||
for _, c := range p.hand {
|
||||
p.cardCounts[c]++
|
||||
func (g *Game) Counts(cards []rune) map[rune]int {
|
||||
m := make(map[rune]int, len(g.cardOrder))
|
||||
for _, c := range cards {
|
||||
m[c]++
|
||||
}
|
||||
|
||||
if wildCard != 0 && p.cardCounts[wildCard] > 0 {
|
||||
if g.wildCard != 0 && m[g.wildCard] > 0 {
|
||||
var maxK rune
|
||||
var maxV int
|
||||
for k, v := range p.cardCounts {
|
||||
if k != wildCard && v > maxV {
|
||||
for k, v := range m {
|
||||
if k != g.wildCard && v > maxV {
|
||||
maxK, maxV = k, v
|
||||
}
|
||||
}
|
||||
|
||||
if maxK != 0 {
|
||||
p.cardCounts[maxK] += p.cardCounts[wildCard]
|
||||
delete(p.cardCounts, wildCard)
|
||||
m[maxK] += m[g.wildCard]
|
||||
delete(m, g.wildCard)
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (g *Game) hasSame(counts map[rune]int) (has1, has2, has3, has4, has5 bool) {
|
||||
for _, c := range counts {
|
||||
func (g *Game) hasSame(cards []rune) (has1, has2, has3, has4, has5 bool) {
|
||||
cnt := g.Counts(cards)
|
||||
for _, c := range cnt {
|
||||
switch c {
|
||||
case 1:
|
||||
has1 = true
|
||||
@@ -268,9 +236,9 @@ func (g *Game) hasSame(counts map[rune]int) (has1, has2, has3, has4, has5 bool)
|
||||
}
|
||||
return
|
||||
}
|
||||
func (g *Game) pairs(counts map[rune]int) int {
|
||||
func (g *Game) pairs(cards []rune) int {
|
||||
pairs := 0
|
||||
for _, n := range counts {
|
||||
for _, n := range g.Counts(cards) {
|
||||
if n == 2 {
|
||||
pairs++
|
||||
}
|
||||
|
||||
@@ -26,21 +26,18 @@ func TestHands(t *testing.T) {
|
||||
var game Game
|
||||
game.cardOrder = getOrder(cardTypes1)
|
||||
|
||||
h := Play{hand: []rune("AAA23"), game: &game}
|
||||
// h.generateCounts()
|
||||
h := Play{0, []rune("AAA23"), &game}
|
||||
is.Equal(h.HandType(), "3K-A")
|
||||
|
||||
h = Play{hand: []rune("JJJJJ"), game:&game}
|
||||
h.generateCounts()
|
||||
|
||||
h = Play{0, []rune("JJJJJ"), &game}
|
||||
is.Equal(h.HandType(), "5K-J")
|
||||
is.Equal(fmt.Sprintf("%x", h.HandStrength()), "7aaaaa")
|
||||
|
||||
h = Play{hand: []rune("KKKKJ"), game: &game}
|
||||
h = Play{0, []rune("KKKKJ"), &game}
|
||||
is.Equal(h.HandType(), "4K-K")
|
||||
is.Equal(fmt.Sprintf("%x", h.HandStrength()), "6cccca")
|
||||
|
||||
h = Play{hand: []rune("QQQJA"), game: &game}
|
||||
h = Play{0, []rune("QQQJA"), &game}
|
||||
is.Equal(h.HandType(), "3K-Q")
|
||||
is.Equal(fmt.Sprintf("%x", h.HandStrength()), "4bbbad")
|
||||
}
|
||||
@@ -57,19 +54,21 @@ func TestExample(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(example))
|
||||
|
||||
score1, score2 := run(scan)
|
||||
is.Equal(score1, uint64(6440))
|
||||
is.Equal(score2, uint64(5905))
|
||||
r, err := run(scan)
|
||||
is.NoErr(err)
|
||||
is.Equal(r.valuePT1, uint64(6440))
|
||||
is.Equal(r.valuePT2, uint64(5905))
|
||||
}
|
||||
|
||||
func TestSolution(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
score1, score2 := run(scan)
|
||||
t.Log("score1", score1)
|
||||
is.Equal(score1, uint64(248559379))
|
||||
r, err := run(scan)
|
||||
is.NoErr(err)
|
||||
t.Log("score1", r.valuePT1)
|
||||
is.Equal(r.valuePT1, uint64(248559379))
|
||||
|
||||
t.Log("score2", score2)
|
||||
is.Equal(score2, uint64(249631254))
|
||||
t.Log("score2", r.valuePT2)
|
||||
is.Equal(r.valuePT2, uint64(249631254))
|
||||
}
|
||||
|
||||
9
day08/example1.txt
Normal file
9
day08/example1.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
RL
|
||||
|
||||
AAA = (BBB, CCC)
|
||||
BBB = (DDD, EEE)
|
||||
CCC = (ZZZ, GGG)
|
||||
DDD = (DDD, DDD)
|
||||
EEE = (EEE, EEE)
|
||||
GGG = (GGG, GGG)
|
||||
ZZZ = (ZZZ, ZZZ)
|
||||
5
day08/example2.txt
Normal file
5
day08/example2.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
LLR
|
||||
|
||||
AAA = (BBB, BBB)
|
||||
BBB = (AAA, ZZZ)
|
||||
ZZZ = (ZZZ, ZZZ)
|
||||
10
day08/example3.txt
Normal file
10
day08/example3.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
LR
|
||||
|
||||
11A = (11B, XXX)
|
||||
11B = (XXX, 11Z)
|
||||
11Z = (11B, XXX)
|
||||
22A = (22B, XXX)
|
||||
22B = (22C, 22C)
|
||||
22C = (22Z, 22Z)
|
||||
22Z = (22B, 22B)
|
||||
XXX = (XXX, XXX)
|
||||
708
day08/input.txt
Normal file
708
day08/input.txt
Normal file
@@ -0,0 +1,708 @@
|
||||
LLLLRLRLRRLRRRLRRLRLRRLRLLRRRLRRLRRRLRLLLRLRRLRLLRRRLRRLRLRRLLRRRLRRRLRLRRLRRRLRRLRRLLRRRLLLLRRLRRLRRLRRRLLLRLRLRLRRLRRRLRLRRRLRLRRRLRRLRRLLRRLLRLRRRLRLRRRLLLRLRRRLRLRRRLRRLRLRRLRRRLRRRLRRLLLRRRLRRLRRLRRLRRRLLLRRLRLRRRLLLLRRRLRRLRRRLLRLRLRRLLRRRLLRLRLRLRRLRRLRRRLRRLLRLRRLRRLLLLRRLRLRRLLRRLLRRLRRLRRRLLLRRRR
|
||||
|
||||
BRR = (LVC, FSJ)
|
||||
BHX = (GMG, QTN)
|
||||
TJD = (HQF, PBJ)
|
||||
JGN = (JXR, DGK)
|
||||
NMC = (VPC, CRF)
|
||||
DVJ = (KMM, DFJ)
|
||||
LML = (MTG, KNX)
|
||||
JKL = (LRX, FRD)
|
||||
FJR = (MHX, SBX)
|
||||
LMC = (QNB, QCK)
|
||||
LJF = (KCJ, HCT)
|
||||
KTL = (XTG, NGM)
|
||||
GJB = (KTQ, KTQ)
|
||||
BXR = (TDR, KMK)
|
||||
GKB = (VXT, NQR)
|
||||
PJL = (FPL, TFX)
|
||||
LNZ = (CJC, DQL)
|
||||
KCG = (KDL, LMF)
|
||||
PGG = (NDL, XXC)
|
||||
PMS = (XQM, DFG)
|
||||
CJF = (MCG, RTJ)
|
||||
JTH = (PGS, SGZ)
|
||||
QBS = (JSC, KMT)
|
||||
DQL = (KRR, PBL)
|
||||
HSF = (SNP, KJR)
|
||||
XVQ = (VQR, HSX)
|
||||
QKF = (PBT, XLC)
|
||||
DNA = (DQL, CJC)
|
||||
LNF = (RVC, TJD)
|
||||
MKT = (LDX, CGC)
|
||||
BXP = (RGX, TTR)
|
||||
SBX = (PGT, JGN)
|
||||
JQK = (HDQ, BHQ)
|
||||
MHL = (TLX, JDN)
|
||||
BBD = (QNJ, BRM)
|
||||
MTT = (BVK, DXB)
|
||||
FVR = (VLN, PRV)
|
||||
RVC = (HQF, PBJ)
|
||||
LDX = (LRS, KBV)
|
||||
BKF = (PXH, TNB)
|
||||
BRM = (XTV, NGH)
|
||||
DDL = (JNG, SFF)
|
||||
BBT = (BQJ, BCN)
|
||||
GPK = (CVK, DDL)
|
||||
TLX = (BDN, XNT)
|
||||
JHL = (BRX, QBT)
|
||||
NTL = (HSR, DJD)
|
||||
XBH = (PJX, JQK)
|
||||
PPF = (LCT, BJL)
|
||||
SFF = (FVR, NFG)
|
||||
HNA = (CTC, BSG)
|
||||
CNG = (DXM, QFN)
|
||||
GML = (NRD, TVN)
|
||||
RHH = (NBT, LJH)
|
||||
LDM = (DDN, TRN)
|
||||
XSK = (PLB, NVJ)
|
||||
NCQ = (MDN, XGT)
|
||||
FCQ = (HCT, KCJ)
|
||||
DRC = (JKL, JNM)
|
||||
SHR = (KLX, VLH)
|
||||
FTP = (DRN, DKV)
|
||||
QBF = (GVS, NXK)
|
||||
GXK = (XDK, LVF)
|
||||
KMK = (VXV, XCS)
|
||||
PKK = (QNJ, BRM)
|
||||
NJH = (TKL, PQK)
|
||||
BRX = (MNM, HVC)
|
||||
VTD = (BJK, LML)
|
||||
QVX = (DVJ, DSF)
|
||||
GRM = (JCV, SQB)
|
||||
RDQ = (HCG, XMB)
|
||||
RGX = (FCN, TPD)
|
||||
HBH = (FPR, DHX)
|
||||
PHM = (JSP, RCR)
|
||||
NBT = (FRG, CMJ)
|
||||
XRH = (HCB, FBM)
|
||||
GMR = (FDJ, NJD)
|
||||
MVG = (RDJ, QSD)
|
||||
BDL = (JSB, TFN)
|
||||
VXT = (MBM, JND)
|
||||
TXC = (QDG, LTV)
|
||||
SRL = (RRX, NDS)
|
||||
SGN = (MPL, CBB)
|
||||
HVH = (SLJ, CBC)
|
||||
VPC = (CCG, QSJ)
|
||||
KCJ = (CKC, TTD)
|
||||
RLT = (LLT, VVL)
|
||||
RXV = (KXQ, VBR)
|
||||
FQS = (STP, BHX)
|
||||
SGC = (RLJ, QGB)
|
||||
XLX = (HRG, DGV)
|
||||
XKV = (QQB, TNQ)
|
||||
SLJ = (GTB, MPF)
|
||||
PKV = (CQN, THS)
|
||||
RPP = (QFT, TNK)
|
||||
DKL = (MFC, MFC)
|
||||
BCG = (FXM, GPR)
|
||||
RFV = (DRC, MPD)
|
||||
VVC = (FGN, CVL)
|
||||
HQB = (QNT, VVC)
|
||||
RRP = (VVC, QNT)
|
||||
TRS = (RCM, GHN)
|
||||
QBT = (HVC, MNM)
|
||||
XKS = (SCC, VXX)
|
||||
TPS = (FMH, KFN)
|
||||
MTS = (VXT, NQR)
|
||||
FXM = (LDM, FQT)
|
||||
LNB = (XJV, SJN)
|
||||
HVF = (QXC, RBH)
|
||||
LSG = (QHM, TSM)
|
||||
JMP = (HBH, NQK)
|
||||
NGM = (KDP, HHP)
|
||||
HCG = (SLR, TSC)
|
||||
HGX = (DFG, XQM)
|
||||
DLG = (BVN, GMM)
|
||||
DJD = (VGP, VML)
|
||||
HBT = (XKL, JBQ)
|
||||
NVJ = (GKX, PKS)
|
||||
CPS = (PKJ, RSV)
|
||||
SKN = (NBT, LJH)
|
||||
CCK = (TTJ, SLV)
|
||||
DXM = (CBN, BXR)
|
||||
RJD = (XJH, SKH)
|
||||
RDJ = (CNF, TTG)
|
||||
PKJ = (BCM, XKC)
|
||||
FQL = (SRV, DFC)
|
||||
KDS = (MFB, CLQ)
|
||||
QKR = (VGD, CXK)
|
||||
XXC = (NFD, SPS)
|
||||
PSQ = (NJH, BLR)
|
||||
BLR = (PQK, TKL)
|
||||
LMX = (DGV, HRG)
|
||||
GCK = (CSR, CSR)
|
||||
GKJ = (JHL, PNN)
|
||||
GVS = (TLN, LJX)
|
||||
FPR = (JCH, GKD)
|
||||
VQV = (DGB, GGN)
|
||||
CPF = (VMH, JQQ)
|
||||
GKD = (SGF, PHM)
|
||||
JNM = (LRX, FRD)
|
||||
CXV = (LNF, HGF)
|
||||
TNK = (RRD, HKC)
|
||||
DXX = (LMC, ZZZ)
|
||||
DGG = (PPF, TRR)
|
||||
MLH = (TVL, PBR)
|
||||
LBC = (LJL, FTR)
|
||||
FVQ = (TBC, LKB)
|
||||
LTF = (CBC, SLJ)
|
||||
TVH = (XMS, GJS)
|
||||
SFB = (TTJ, SLV)
|
||||
LVF = (MBT, SJB)
|
||||
XPP = (QDM, PJL)
|
||||
BVK = (RPV, JMP)
|
||||
VGD = (MRX, FJR)
|
||||
FRD = (XBH, CDN)
|
||||
LKM = (CMF, XNS)
|
||||
TCJ = (MMS, PGG)
|
||||
DHQ = (MTT, BKS)
|
||||
HDQ = (GPH, XKH)
|
||||
KTJ = (QQT, MKR)
|
||||
NMQ = (VFK, VSD)
|
||||
RSK = (QDM, PJL)
|
||||
XQC = (KFP, HVB)
|
||||
LQN = (NGM, XTG)
|
||||
TKG = (XDQ, XDQ)
|
||||
KBB = (VQR, HSX)
|
||||
TQQ = (QDG, LTV)
|
||||
SQN = (TDQ, XKV)
|
||||
TSM = (TSH, MRP)
|
||||
KPH = (THS, CQN)
|
||||
HCB = (DVL, RTV)
|
||||
MLR = (GHT, NSN)
|
||||
BFM = (GCK, SLX)
|
||||
GXQ = (QKM, JJL)
|
||||
GNF = (HRQ, XTK)
|
||||
TRR = (BJL, LCT)
|
||||
AAA = (QNB, QCK)
|
||||
SDL = (KJX, LSN)
|
||||
DKV = (KBB, XVQ)
|
||||
RMR = (MQR, CPR)
|
||||
MQC = (CBV, SRP)
|
||||
PRV = (KDS, FBX)
|
||||
GTB = (CCK, SFB)
|
||||
SNP = (PXX, SHR)
|
||||
NTR = (VHT, KXK)
|
||||
MKJ = (DDL, CVK)
|
||||
LSQ = (HSF, RMN)
|
||||
TTJ = (CBH, QKF)
|
||||
DNH = (MVG, JCJ)
|
||||
KMM = (KPH, PKV)
|
||||
NTT = (RQK, PFK)
|
||||
QMF = (BFM, PJB)
|
||||
RJB = (RBH, QXC)
|
||||
LRS = (MJT, BVM)
|
||||
CJG = (RMR, BMN)
|
||||
DVQ = (GXM, DDH)
|
||||
MFC = (LMC, LMC)
|
||||
XTG = (HHP, KDP)
|
||||
HKB = (RDQ, TVT)
|
||||
PKS = (JQM, DGG)
|
||||
BJK = (KNX, MTG)
|
||||
TVT = (XMB, HCG)
|
||||
JNR = (JHG, JLN)
|
||||
VFK = (XKS, QBH)
|
||||
NPC = (PKK, BBD)
|
||||
PXX = (KLX, VLH)
|
||||
XLC = (NST, BXP)
|
||||
CBB = (LMX, XLX)
|
||||
KLX = (MSH, LCF)
|
||||
CLQ = (JNF, JNC)
|
||||
TSS = (MKR, QQT)
|
||||
SSS = (RMQ, RCS)
|
||||
QSD = (TTG, CNF)
|
||||
NHG = (DVQ, VNB)
|
||||
CTC = (VCN, RJD)
|
||||
THS = (QRH, GPT)
|
||||
KDR = (RTK, GKJ)
|
||||
NTD = (CGG, SPN)
|
||||
GHP = (NCQ, FCD)
|
||||
KXQ = (RLS, VRM)
|
||||
GNV = (BQJ, BCN)
|
||||
DXQ = (QHC, FXN)
|
||||
RQB = (FVQ, TNF)
|
||||
CNF = (TXC, TQQ)
|
||||
BGB = (QQS, LRV)
|
||||
ZZZ = (QCK, QNB)
|
||||
NFM = (MGV, VTD)
|
||||
MFD = (DBF, KSN)
|
||||
NST = (RGX, TTR)
|
||||
XJV = (LGL, LGL)
|
||||
TRQ = (TVH, KJL)
|
||||
PPV = (CJP, VHH)
|
||||
DNV = (DBM, VGJ)
|
||||
JBQ = (MHL, RFN)
|
||||
HRG = (JFD, VQP)
|
||||
RMB = (JKJ, JGJ)
|
||||
RGQ = (RSK, XPP)
|
||||
KHF = (TJG, KPX)
|
||||
HPZ = (BSG, CTC)
|
||||
LFJ = (TSN, NMB)
|
||||
MBT = (XRC, PJR)
|
||||
QFN = (CBN, BXR)
|
||||
QSJ = (BRS, BKF)
|
||||
XJH = (RSF, VNP)
|
||||
GST = (LVF, XDK)
|
||||
DDN = (NMS, RLT)
|
||||
CXK = (FJR, MRX)
|
||||
PHH = (FPB, TCJ)
|
||||
XHV = (KTJ, TSS)
|
||||
VHT = (NPC, DMG)
|
||||
RNL = (NHG, DVN)
|
||||
TKL = (KPN, FKX)
|
||||
DGB = (GPJ, QMF)
|
||||
PNN = (QBT, BRX)
|
||||
TBC = (NTR, FKG)
|
||||
PGS = (QDT, JQL)
|
||||
SLX = (CSR, LNB)
|
||||
BVV = (LVC, FSJ)
|
||||
JQL = (MLH, GSC)
|
||||
PXH = (CJF, CKM)
|
||||
LHM = (DSF, DVJ)
|
||||
NND = (NTD, DTB)
|
||||
MFB = (JNF, JNC)
|
||||
TTR = (FCN, TPD)
|
||||
HRQ = (JTD, JTD)
|
||||
SLR = (TXT, JSN)
|
||||
VQP = (XPK, XGB)
|
||||
QHM = (MRP, TSH)
|
||||
RTJ = (PXB, TLP)
|
||||
QQT = (RRL, QHQ)
|
||||
CSR = (XJV, XJV)
|
||||
CJP = (CJG, HQQ)
|
||||
RMC = (MPD, DRC)
|
||||
XMS = (LXX, GPN)
|
||||
HSR = (VGP, VML)
|
||||
MNM = (VSS, QXR)
|
||||
SJN = (LGL, LNZ)
|
||||
KBV = (MJT, BVM)
|
||||
KFN = (NRC, VSG)
|
||||
JNC = (RHR, LFJ)
|
||||
MPF = (SFB, CCK)
|
||||
QVK = (GNK, BCG)
|
||||
NJD = (KCG, LDB)
|
||||
DBM = (MJG, MFD)
|
||||
NKF = (GGN, DGB)
|
||||
BCN = (JNR, MHK)
|
||||
GNK = (FXM, GPR)
|
||||
KMT = (HFC, CPS)
|
||||
FDJ = (KCG, LDB)
|
||||
LVD = (PHH, QDR)
|
||||
FCN = (VDP, MQC)
|
||||
QQB = (GJB, GJB)
|
||||
PLF = (JNL, HBT)
|
||||
QDM = (FPL, TFX)
|
||||
GXM = (CLD, NNL)
|
||||
MRV = (BCG, GNK)
|
||||
LKB = (NTR, FKG)
|
||||
TTG = (TQQ, TXC)
|
||||
GFD = (VSD, VFK)
|
||||
RCS = (KQQ, DNH)
|
||||
QXR = (FCQ, LJF)
|
||||
HMQ = (RJQ, FQL)
|
||||
VCN = (SKH, XJH)
|
||||
QQG = (HSR, DJD)
|
||||
HGF = (RVC, TJD)
|
||||
XMB = (TSC, SLR)
|
||||
PJB = (GCK, SLX)
|
||||
HFC = (RSV, PKJ)
|
||||
JJL = (GXK, GST)
|
||||
QTN = (JLV, SGX)
|
||||
KDP = (GNV, BBT)
|
||||
VRF = (TFN, JSB)
|
||||
GPN = (CPF, SRQ)
|
||||
TSC = (TXT, JSN)
|
||||
CRF = (QSJ, CCG)
|
||||
TNF = (TBC, LKB)
|
||||
VLH = (LCF, MSH)
|
||||
BCV = (JSC, KMT)
|
||||
NNL = (KVX, FQS)
|
||||
RVT = (HCB, FBM)
|
||||
QHC = (QKV, NCJ)
|
||||
VDP = (CBV, SRP)
|
||||
CBV = (VQV, NKF)
|
||||
CMF = (XHV, TPR)
|
||||
TRN = (RLT, NMS)
|
||||
JSB = (XTH, TRS)
|
||||
CFC = (TVT, RDQ)
|
||||
KDL = (TKG, TKG)
|
||||
TTD = (BBC, GHP)
|
||||
KJR = (PXX, SHR)
|
||||
MTV = (GVS, NXK)
|
||||
BVN = (KDR, PVP)
|
||||
DXB = (RPV, JMP)
|
||||
FSJ = (QPQ, GML)
|
||||
PBJ = (LQN, KTL)
|
||||
PXB = (BDL, VRF)
|
||||
NDS = (BGB, NGX)
|
||||
CBN = (KMK, TDR)
|
||||
NFG = (VLN, PRV)
|
||||
JTD = (PGS, PGS)
|
||||
MKR = (QHQ, RRL)
|
||||
JSN = (RFV, RMC)
|
||||
CVK = (SFF, JNG)
|
||||
FGN = (BVQ, XQC)
|
||||
HHF = (RPS, QQF)
|
||||
PLB = (PKS, GKX)
|
||||
BJB = (QMC, GPG)
|
||||
STP = (QTN, GMG)
|
||||
DGK = (RKK, BVT)
|
||||
JJM = (VGD, CXK)
|
||||
LTS = (QPN, BCL)
|
||||
LVC = (QPQ, GML)
|
||||
QNB = (GJN, RVB)
|
||||
RBH = (HMQ, HPS)
|
||||
NQK = (DHX, FPR)
|
||||
MRP = (BDT, SGN)
|
||||
JQM = (TRR, PPF)
|
||||
TSH = (BDT, SGN)
|
||||
JLN = (JCC, FCB)
|
||||
BRP = (LDX, CGC)
|
||||
SJC = (HRQ, HRQ)
|
||||
LJL = (BVB, PPV)
|
||||
SPN = (SDL, VHM)
|
||||
SDM = (DDF, LTS)
|
||||
LJH = (FRG, CMJ)
|
||||
CMG = (MKD, JGT)
|
||||
GPR = (LDM, FQT)
|
||||
QPQ = (NRD, TVN)
|
||||
JCJ = (RDJ, QSD)
|
||||
HSX = (CMG, SHF)
|
||||
VML = (RMB, MHC)
|
||||
DHX = (JCH, GKD)
|
||||
MTG = (FPX, SPD)
|
||||
BDT = (MPL, CBB)
|
||||
CJC = (PBL, KRR)
|
||||
JLS = (LJL, FTR)
|
||||
HQF = (LQN, KTL)
|
||||
HQQ = (RMR, BMN)
|
||||
QMC = (RBP, PXD)
|
||||
RPV = (HBH, NQK)
|
||||
JHG = (JCC, FCB)
|
||||
TPD = (VDP, MQC)
|
||||
BHQ = (XKH, GPH)
|
||||
XKC = (HDD, GXR)
|
||||
RPS = (KJP, KJP)
|
||||
QNT = (CVL, FGN)
|
||||
JSC = (HFC, CPS)
|
||||
KXG = (DTB, NTD)
|
||||
CKM = (RTJ, MCG)
|
||||
FTD = (KPX, TJG)
|
||||
VSD = (XKS, QBH)
|
||||
MCG = (TLP, PXB)
|
||||
XKH = (HLP, CXV)
|
||||
TNB = (CJF, CKM)
|
||||
XTH = (RCM, GHN)
|
||||
DFN = (GMR, DSS)
|
||||
LMF = (TKG, XST)
|
||||
FMH = (NRC, VSG)
|
||||
XCS = (JTS, GRM)
|
||||
GVF = (NDS, RRX)
|
||||
CXM = (HGX, PMS)
|
||||
VRM = (XJT, DXQ)
|
||||
JLV = (QVX, LHM)
|
||||
JCH = (PHM, SGF)
|
||||
NMS = (VVL, LLT)
|
||||
BHS = (XJR, LKM)
|
||||
CKC = (BBC, GHP)
|
||||
CBH = (XLC, PBT)
|
||||
PRL = (QFT, TNK)
|
||||
SDF = (VTD, MGV)
|
||||
RVB = (MLR, XHT)
|
||||
GPT = (PLF, MJX)
|
||||
KRR = (RVT, XRH)
|
||||
GXR = (BVV, BRR)
|
||||
NSN = (RGQ, JMQ)
|
||||
KJX = (TCR, MSL)
|
||||
PHL = (TSM, QHM)
|
||||
MQR = (MTS, GKB)
|
||||
XDK = (SJB, MBT)
|
||||
NRC = (DGN, BJB)
|
||||
JQQ = (LBC, JLS)
|
||||
JTS = (JCV, SQB)
|
||||
RLJ = (JJM, QKR)
|
||||
DTB = (CGG, SPN)
|
||||
BRS = (PXH, TNB)
|
||||
SRV = (SPC, DNV)
|
||||
MNP = (JJL, QKM)
|
||||
KTQ = (XSK, XSK)
|
||||
FPX = (SJC, GNF)
|
||||
VBR = (VRM, RLS)
|
||||
KSN = (HQB, RRP)
|
||||
RJQ = (SRV, DFC)
|
||||
BKS = (BVK, DXB)
|
||||
BVB = (VHH, CJP)
|
||||
XTK = (JTD, JTH)
|
||||
PBT = (BXP, NST)
|
||||
PVP = (RTK, GKJ)
|
||||
QPN = (BCV, QBS)
|
||||
QQF = (KJP, HPZ)
|
||||
QRH = (PLF, MJX)
|
||||
GHS = (BKN, TPS)
|
||||
RCM = (MNP, GXQ)
|
||||
DCT = (DDF, LTS)
|
||||
JLC = (HGX, PMS)
|
||||
VNC = (XSK, CXZ)
|
||||
BQJ = (MHK, JNR)
|
||||
SHF = (JGT, MKD)
|
||||
FXN = (QKV, NCJ)
|
||||
FPB = (PGG, MMS)
|
||||
JGJ = (KXG, NND)
|
||||
VBM = (PSQ, QKN)
|
||||
GKX = (DGG, JQM)
|
||||
DSF = (KMM, DFJ)
|
||||
CMJ = (GPK, MKJ)
|
||||
NCJ = (SDM, DCT)
|
||||
MKD = (GQG, DHQ)
|
||||
CFZ = (RQB, SHH)
|
||||
RQK = (DKL, DKL)
|
||||
XGT = (HPQ, VRQ)
|
||||
SRP = (NKF, VQV)
|
||||
BSG = (VCN, RJD)
|
||||
XRC = (NFM, SDF)
|
||||
DVL = (SRL, GVF)
|
||||
HVB = (HXS, MLD)
|
||||
MPD = (JNM, JKL)
|
||||
JSP = (PHL, LSG)
|
||||
BCR = (XJR, LKM)
|
||||
PQK = (KPN, FKX)
|
||||
FCD = (XGT, MDN)
|
||||
MDL = (JLC, CXM)
|
||||
FBX = (CLQ, MFB)
|
||||
VNP = (RGM, GHS)
|
||||
HMK = (RMN, HSF)
|
||||
SJB = (PJR, XRC)
|
||||
JFD = (XPK, XGB)
|
||||
HHP = (GNV, BBT)
|
||||
TVN = (VBM, KJN)
|
||||
DMG = (PKK, BBD)
|
||||
RGM = (BKN, TPS)
|
||||
TRF = (KXQ, VBR)
|
||||
XHT = (NSN, GHT)
|
||||
DFJ = (KPH, PKV)
|
||||
KJP = (CTC, BSG)
|
||||
LLT = (NTS, LVD)
|
||||
RMN = (SNP, KJR)
|
||||
GSC = (TVL, PBR)
|
||||
RSV = (XKC, BCM)
|
||||
TLP = (VRF, BDL)
|
||||
GGN = (GPJ, QMF)
|
||||
XJR = (CMF, XNS)
|
||||
GQG = (BKS, MTT)
|
||||
JPN = (MRV, QVK)
|
||||
RSF = (RGM, GHS)
|
||||
QQS = (DLG, JPV)
|
||||
DGV = (VQP, JFD)
|
||||
JDN = (XNT, BDN)
|
||||
LMA = (QDT, JQL)
|
||||
QDG = (QGC, DTX)
|
||||
HDD = (BVV, BRR)
|
||||
RRD = (CNG, XLJ)
|
||||
QBH = (VXX, SCC)
|
||||
GPH = (HLP, CXV)
|
||||
CVN = (MRV, QVK)
|
||||
RLS = (XJT, DXQ)
|
||||
QKN = (NJH, BLR)
|
||||
NRD = (VBM, KJN)
|
||||
NMB = (HVF, RJB)
|
||||
XNT = (RXV, TRF)
|
||||
XNS = (XHV, TPR)
|
||||
SGX = (LHM, QVX)
|
||||
NTS = (PHH, QDR)
|
||||
SPS = (LTF, HVH)
|
||||
KPX = (BCR, BHS)
|
||||
GNM = (RPS, RPS)
|
||||
CXZ = (NVJ, PLB)
|
||||
VVL = (LVD, NTS)
|
||||
VTC = (NHG, DVN)
|
||||
PXD = (BHH, SSS)
|
||||
TVL = (MKT, BRP)
|
||||
TPR = (KTJ, TSS)
|
||||
MJX = (JNL, HBT)
|
||||
BKN = (FMH, KFN)
|
||||
MBM = (BVC, FTP)
|
||||
RTV = (GVF, SRL)
|
||||
GPG = (PXD, RBP)
|
||||
KXK = (DMG, NPC)
|
||||
JPV = (GMM, BVN)
|
||||
LXP = (VPC, CRF)
|
||||
RMQ = (DNH, KQQ)
|
||||
DRN = (KBB, XVQ)
|
||||
MMS = (XXC, NDL)
|
||||
GMG = (SGX, JLV)
|
||||
MJT = (KHF, FTD)
|
||||
XJT = (QHC, FXN)
|
||||
JMQ = (XPP, RSK)
|
||||
QCS = (TVH, KJL)
|
||||
BVC = (DRN, DKV)
|
||||
SPC = (DBM, VGJ)
|
||||
SHH = (TNF, FVQ)
|
||||
VGA = (PLB, NVJ)
|
||||
RKK = (JPN, CVN)
|
||||
SCC = (TRQ, QCS)
|
||||
CDN = (JQK, PJX)
|
||||
VSS = (LJF, FCQ)
|
||||
JNF = (LFJ, RHR)
|
||||
VGP = (MHC, RMB)
|
||||
VGJ = (MJG, MFD)
|
||||
QGC = (RHH, SKN)
|
||||
RKJ = (KTQ, VNC)
|
||||
DTX = (SKN, RHH)
|
||||
HPQ = (VDR, SGC)
|
||||
CCG = (BRS, BKF)
|
||||
VLN = (FBX, KDS)
|
||||
BHH = (RMQ, RCS)
|
||||
BBC = (FCD, NCQ)
|
||||
JCV = (GNM, GNM)
|
||||
TNQ = (GJB, RKJ)
|
||||
QNJ = (NGH, XTV)
|
||||
GHT = (RGQ, JMQ)
|
||||
LJX = (CFC, HKB)
|
||||
TLN = (HKB, CFC)
|
||||
PFK = (DKL, LFL)
|
||||
PJR = (SDF, NFM)
|
||||
JNG = (NFG, FVR)
|
||||
PJX = (BHQ, HDQ)
|
||||
VHH = (CJG, HQQ)
|
||||
RTK = (PNN, JHL)
|
||||
XGB = (MLN, SQN)
|
||||
JCC = (NQX, NTT)
|
||||
BVT = (CVN, JPN)
|
||||
HPS = (RJQ, FQL)
|
||||
TCR = (DFN, RHS)
|
||||
LLA = (SHH, RQB)
|
||||
NGX = (QQS, LRV)
|
||||
SLV = (CBH, QKF)
|
||||
BMN = (CPR, MQR)
|
||||
XKL = (RFN, MHL)
|
||||
CGG = (VHM, SDL)
|
||||
KJN = (PSQ, QKN)
|
||||
LDB = (KDL, LMF)
|
||||
SPD = (SJC, GNF)
|
||||
VDR = (RLJ, QGB)
|
||||
DDF = (QPN, BCL)
|
||||
KQQ = (MVG, JCJ)
|
||||
DSS = (FDJ, NJD)
|
||||
NFD = (HVH, LTF)
|
||||
GPJ = (BFM, PJB)
|
||||
LGL = (DQL, CJC)
|
||||
TDQ = (QQB, TNQ)
|
||||
RCR = (PHL, LSG)
|
||||
SKH = (VNP, RSF)
|
||||
DGN = (QMC, GPG)
|
||||
NGH = (RNL, VTC)
|
||||
TSN = (HVF, RJB)
|
||||
MGV = (LML, BJK)
|
||||
QHQ = (LXP, NMC)
|
||||
KJL = (GJS, XMS)
|
||||
RBP = (BHH, SSS)
|
||||
QDR = (FPB, TCJ)
|
||||
RHR = (NMB, TSN)
|
||||
NXK = (LJX, TLN)
|
||||
FCB = (NQX, NTT)
|
||||
TFN = (TRS, XTH)
|
||||
MJG = (KSN, DBF)
|
||||
BVQ = (KFP, HVB)
|
||||
GMM = (PVP, KDR)
|
||||
MDN = (VRQ, HPQ)
|
||||
LTV = (DTX, QGC)
|
||||
LRV = (DLG, JPV)
|
||||
MHC = (JKJ, JGJ)
|
||||
DFC = (DNV, SPC)
|
||||
LXV = (SHH, RQB)
|
||||
PBL = (RVT, XRH)
|
||||
BDN = (RXV, TRF)
|
||||
JKJ = (KXG, NND)
|
||||
MSH = (MTV, QBF)
|
||||
NDL = (SPS, NFD)
|
||||
FKG = (VHT, KXK)
|
||||
PBR = (MKT, BRP)
|
||||
VSG = (BJB, DGN)
|
||||
RRX = (BGB, NGX)
|
||||
NQR = (JND, MBM)
|
||||
MRX = (MHX, SBX)
|
||||
DVN = (DVQ, VNB)
|
||||
HKC = (CNG, XLJ)
|
||||
PGT = (JXR, DGK)
|
||||
DBF = (HQB, RRP)
|
||||
FRG = (GPK, MKJ)
|
||||
DFG = (NMQ, GFD)
|
||||
QDT = (MLH, GSC)
|
||||
KVX = (STP, BHX)
|
||||
LCT = (MDL, KCL)
|
||||
LSN = (TCR, MSL)
|
||||
TXT = (RMC, RFV)
|
||||
MXM = (LXV, CFZ)
|
||||
TJG = (BHS, BCR)
|
||||
BCM = (GXR, HDD)
|
||||
FKX = (NTL, QQG)
|
||||
SRQ = (JQQ, VMH)
|
||||
BCL = (BCV, QBS)
|
||||
LRX = (CDN, XBH)
|
||||
RHS = (DSS, GMR)
|
||||
CLD = (FQS, KVX)
|
||||
XLJ = (DXM, QFN)
|
||||
KCL = (CXM, JLC)
|
||||
HXS = (PRL, RPP)
|
||||
JND = (BVC, FTP)
|
||||
VQR = (SHF, CMG)
|
||||
VNB = (DDH, GXM)
|
||||
QGB = (JJM, QKR)
|
||||
CVL = (BVQ, XQC)
|
||||
RFN = (JDN, TLX)
|
||||
FBM = (DVL, RTV)
|
||||
TFX = (LSQ, HMK)
|
||||
XQM = (NMQ, GFD)
|
||||
BJL = (KCL, MDL)
|
||||
FTR = (PPV, BVB)
|
||||
KNX = (FPX, SPD)
|
||||
MHK = (JHG, JLN)
|
||||
TDR = (XCS, VXV)
|
||||
HVC = (VSS, QXR)
|
||||
QXC = (HPS, HMQ)
|
||||
RRL = (NMC, LXP)
|
||||
MLD = (PRL, RPP)
|
||||
LCF = (MTV, QBF)
|
||||
VXV = (JTS, GRM)
|
||||
XTV = (RNL, VTC)
|
||||
LFL = (MFC, DXX)
|
||||
CBC = (GTB, MPF)
|
||||
CQN = (GPT, QRH)
|
||||
DDH = (NNL, CLD)
|
||||
GHN = (GXQ, MNP)
|
||||
JGT = (DHQ, GQG)
|
||||
HCT = (CKC, TTD)
|
||||
QCK = (GJN, RVB)
|
||||
SGF = (JSP, RCR)
|
||||
MPL = (XLX, LMX)
|
||||
XDQ = (LXV, LXV)
|
||||
MLN = (TDQ, XKV)
|
||||
SGZ = (JQL, QDT)
|
||||
VRQ = (SGC, VDR)
|
||||
FPL = (LSQ, HMK)
|
||||
SQB = (GNM, HHF)
|
||||
MHX = (PGT, JGN)
|
||||
QFT = (HKC, RRD)
|
||||
LXX = (CPF, SRQ)
|
||||
CPR = (GKB, MTS)
|
||||
HLP = (LNF, HGF)
|
||||
GJS = (GPN, LXX)
|
||||
QKV = (DCT, SDM)
|
||||
XST = (XDQ, MXM)
|
||||
VXX = (QCS, TRQ)
|
||||
KFP = (HXS, MLD)
|
||||
MSL = (RHS, DFN)
|
||||
NQX = (RQK, PFK)
|
||||
CGC = (LRS, KBV)
|
||||
FQT = (TRN, DDN)
|
||||
VMH = (LBC, JLS)
|
||||
VHM = (LSN, KJX)
|
||||
JXR = (BVT, RKK)
|
||||
KPN = (QQG, NTL)
|
||||
QKM = (GST, GXK)
|
||||
JNL = (XKL, JBQ)
|
||||
BVM = (KHF, FTD)
|
||||
XPK = (SQN, MLN)
|
||||
GJN = (MLR, XHT)
|
||||
149
day08/main.go
Normal file
149
day08/main.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result, err := aoc.Runner(run)
|
||||
if err != nil {
|
||||
fmt.Println("ERR", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("result", result)
|
||||
}
|
||||
|
||||
type result struct {
|
||||
stepsPT1 uint64
|
||||
stepsPT2 uint64
|
||||
}
|
||||
|
||||
func (r result) String() string {
|
||||
return fmt.Sprintf("solution 1: %v\nsolution 2: %v\n", r.stepsPT1, r.stepsPT2)
|
||||
}
|
||||
|
||||
func run(scan *bufio.Scanner) (*result, error) {
|
||||
var path []rune
|
||||
m := make(nodeMap)
|
||||
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
if len(text) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(path) == 0 {
|
||||
fmt.Println("path", text)
|
||||
path = []rune(strings.TrimSpace(text))
|
||||
continue
|
||||
}
|
||||
|
||||
n := &node{}
|
||||
i, err := fmt.Sscanf(text, "%s = (%s %s", &n.value, &n.lvalue, &n.rvalue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n.lvalue = strings.TrimRight(n.lvalue, ",)")
|
||||
n.rvalue = strings.TrimRight(n.rvalue, ",)")
|
||||
m[n.value] = n
|
||||
|
||||
fmt.Println("value", i, n.value, n.lvalue, n.rvalue)
|
||||
}
|
||||
if err := m.mapNodes(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
steps1 := m.SolvePT1(path)
|
||||
steps2 := m.SolvePT2(path)
|
||||
|
||||
return &result{steps1, steps2}, nil
|
||||
}
|
||||
|
||||
type node struct {
|
||||
value string
|
||||
lvalue, rvalue string
|
||||
left, right *node
|
||||
}
|
||||
|
||||
type nodeMap map[string]*node
|
||||
|
||||
func (m nodeMap) mapNodes() error {
|
||||
for k, v := range m {
|
||||
if ptr, ok := m[v.lvalue]; ok {
|
||||
v.left = ptr
|
||||
} else {
|
||||
return fmt.Errorf("%s L-> %s not found", k, v.lvalue)
|
||||
}
|
||||
if ptr, ok := m[v.rvalue]; ok {
|
||||
v.right = ptr
|
||||
} else {
|
||||
return fmt.Errorf("%s R-> %s not found", k, v.rvalue)
|
||||
}
|
||||
|
||||
m[k] = v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m nodeMap) solver(start string, isEnd func(string) bool, path []rune) uint64 {
|
||||
position, ok := m[start]
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
var i int
|
||||
var steps uint64
|
||||
|
||||
for steps < ^uint64(0) {
|
||||
steps++
|
||||
if path[i] == 'R' {
|
||||
// fmt.Println("step", steps, position.value, "R->", position.rvalue)
|
||||
position = position.right
|
||||
} else {
|
||||
// fmt.Println("step", steps, position.value, "L->", position.lvalue)
|
||||
position = position.left
|
||||
}
|
||||
|
||||
if isEnd(position.value) {
|
||||
break
|
||||
}
|
||||
|
||||
i++
|
||||
if i > len(path)-1 {
|
||||
i = 0
|
||||
}
|
||||
}
|
||||
return steps
|
||||
}
|
||||
|
||||
func (m nodeMap) SolvePT1(path []rune) uint64 {
|
||||
fmt.Println("---- PART 1 BEGIN ----")
|
||||
defer fmt.Println("---- PART 1 END ----")
|
||||
|
||||
return m.solver("AAA", func(s string) bool { return s == "ZZZ" }, path)
|
||||
}
|
||||
|
||||
func (m nodeMap) SolvePT2(path []rune) uint64 {
|
||||
fmt.Println("---- PART 2 BEGIN ----")
|
||||
defer fmt.Println("---- PART 2 END ----")
|
||||
|
||||
var starts []*node
|
||||
|
||||
for k, n := range m {
|
||||
if strings.HasSuffix(k, "A") {
|
||||
fmt.Println("start", k)
|
||||
starts = append(starts, n)
|
||||
}
|
||||
}
|
||||
|
||||
loops := make([]uint64, len(starts))
|
||||
for i, n := range starts {
|
||||
loops[i] = m.solver(n.value, func(s string) bool { return strings.HasSuffix(s, "Z") }, path)
|
||||
}
|
||||
return aoc.LCM(loops...)
|
||||
}
|
||||
80
day08/main_test.go
Normal file
80
day08/main_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
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 example3.txt
|
||||
var example3 []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.stepsPT1)
|
||||
is.Equal(result.stepsPT1, uint64(2))
|
||||
}
|
||||
|
||||
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.stepsPT1)
|
||||
is.Equal(result.stepsPT1, uint64(6))
|
||||
}
|
||||
|
||||
func TestExample3(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(example3))
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
t.Log(result.stepsPT2)
|
||||
is.Equal(result.stepsPT2, uint64(6))
|
||||
}
|
||||
|
||||
func TestInput(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
t.Log("part1 solution", result.stepsPT1)
|
||||
is.Equal(result.stepsPT1, uint64(14429))
|
||||
|
||||
t.Log("part2 solution", result.stepsPT2)
|
||||
is.Equal(result.stepsPT2, uint64(10921547990923))
|
||||
}
|
||||
|
||||
// first: 14429
|
||||
// second: 10921547990923
|
||||
|
||||
// Brüt
|
||||
// stops 1 steps 13201
|
||||
// stops 2 steps 620447
|
||||
// stops 3 steps 36606373
|
||||
// stops 4 steps 2232988753
|
||||
// stops 5 steps 149610246451
|
||||
3
day09/example.txt
Normal file
3
day09/example.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
0 3 6 9 12 15
|
||||
1 3 6 10 15 21
|
||||
10 13 16 21 30 45
|
||||
200
day09/input.txt
Normal file
200
day09/input.txt
Normal file
@@ -0,0 +1,200 @@
|
||||
28 38 58 115 255 558 1167 2343 4564 8699 16328 30378 56447 105549 199601 381868 735876 1418100 2712150 5115341 9472583
|
||||
24 34 56 103 191 343 593 990 1602 2520 3862 5777 8449 12101 16999 23456 31836 42558 56100 73003 93875
|
||||
12 30 66 118 187 291 486 901 1807 3760 7885 16402 33536 67001 130303 246169 451478 804146 1392500 2347766 3860393
|
||||
11 7 -1 -10 4 101 392 1052 2337 4631 8595 15584 28661 54781 109041 222274 453659 910327 1775963 3349730 6094694
|
||||
13 26 56 110 200 360 677 1347 2785 5847 12267 25493 52275 105732 211455 420013 833076 1658291 3323777 6713131 13636877
|
||||
24 36 50 68 92 124 166 220 288 372 474 596 740 908 1102 1324 1576 1860 2178 2532 2924
|
||||
4 10 18 35 81 207 523 1232 2664 5299 9766 16819 27345 42607 65306 103013 177906 352348 792280 1916515 4732055
|
||||
2 4 15 46 115 246 479 915 1841 4022 9326 21995 51143 115539 252570 534754 1099830 2205374 4328183 8346246 15873877
|
||||
6 16 41 104 240 508 1016 1959 3670 6684 11815 20246 33632 54216 84958 129677 193206 281560 402117 563812 777344
|
||||
10 24 59 127 240 410 649 969 1382 1900 2535 3299 4204 5262 6485 7885 9474 11264 13267 15495 17960
|
||||
1 3 19 65 161 334 621 1072 1753 2749 4167 6139 8825 12416 17137 23250 31057 40903 53179 68325 86833
|
||||
1 3 14 46 118 256 493 869 1431 2233 3336 4808 6724 9166 12223 15991 20573 26079 32626 40338 49346
|
||||
5 20 54 111 200 339 551 863 1338 2203 4189 9270 22068 52271 118490 254073 515553 994838 1837662 3275301 5689494
|
||||
11 19 37 74 152 315 630 1176 2019 3189 4728 6991 11599 23863 58350 151043 385257 945993 2232085 5082986 11226568
|
||||
-6 -5 -1 6 16 29 45 64 86 111 139 170 204 241 281 324 370 419 471 526 584
|
||||
19 44 79 123 175 234 299 369 443 520 599 679 759 838 915 989 1059 1124 1183 1235 1279
|
||||
20 26 41 76 144 261 459 824 1572 3189 6707 14297 30581 65483 140200 299218 633600 1324592 2722729 5487182 10824554
|
||||
2 13 49 134 316 686 1400 2714 5060 9211 16601 29879 53781 96407 171038 298877 513930 873445 1482345 2550372 4520094
|
||||
7 22 55 116 218 381 645 1090 1862 3209 5540 9533 16335 27918 47680 81409 138761 235440 396309 659706 1083288
|
||||
23 34 43 54 73 105 151 202 234 223 220 555 2284 8074 23894 62315 149406 340397 757350 1681105 3771572
|
||||
-2 9 31 72 157 346 769 1701 3724 8065 17266 36441 75513 153008 302220 580858 1085650 1973817 3493849 6028622 10154597
|
||||
17 35 83 175 326 554 878 1305 1800 2233 2292 1349 -1702 -8485 -20570 -37084 -47977 -18173 145725 659887 1980386
|
||||
6 19 49 119 273 598 1257 2530 4856 8858 15310 24963 38082 53479 66865 68818 44405 -18660 -94790 -14282 809438
|
||||
17 21 22 20 15 7 -4 -18 -35 -55 -78 -104 -133 -165 -200 -238 -279 -323 -370 -420 -473
|
||||
8 23 59 139 312 672 1383 2710 5056 9005 15371 25253 40096 61758 92583 135480 194008 272467 375995 510671 683624
|
||||
9 16 34 63 103 154 216 289 373 468 574 691 819 958 1108 1269 1441 1624 1818 2023 2239
|
||||
8 19 59 140 275 481 794 1315 2308 4381 8817 18206 37692 77458 157694 318613 640892 1287715 2591041 5226414 10560561
|
||||
8 21 37 57 82 107 117 88 -4 -163 -339 -377 54 1555 5117 12270 25264 47285 82709 137397 219034
|
||||
22 34 44 52 58 62 64 64 62 58 52 44 34 22 8 -8 -26 -46 -68 -92 -118
|
||||
28 57 114 220 416 779 1446 2651 4785 8494 14832 25483 43057 71450 116238 185052 287858 437047 647230 934638 1316054
|
||||
16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96
|
||||
28 39 48 62 97 180 347 630 1022 1413 1518 905 -557 -1064 7553 50137 189888 570667 1494764 3559032 7883557
|
||||
5 0 3 30 106 262 542 1035 1947 3728 7269 14184 27192 50614 91000 157901 264801 430224 679031 1043922 1567158
|
||||
4 21 55 119 239 461 864 1591 2913 5356 9967 18894 36631 72557 145803 294037 588486 1158435 2229571 4181885 7634411
|
||||
8 11 15 33 81 182 384 805 1728 3777 8206 17321 35023 67400 123199 213865 352632 551879 817609 1139457 1474069
|
||||
6 15 30 69 162 358 754 1560 3223 6658 13679 27799 55705 109973 214073 411584 783020 1476065 2758724 5110417 9373988
|
||||
18 26 37 54 84 138 231 382 614 954 1433 2086 2952 4074 5499 7278 9466 12122 15309 19094 23548
|
||||
3 -2 -7 -12 -17 -22 -27 -32 -37 -42 -47 -52 -57 -62 -67 -72 -77 -82 -87 -92 -97
|
||||
16 32 61 121 242 466 847 1451 2356 3652 5441 7837 10966 14966 19987 26191 33752 42856 53701 66497 81466
|
||||
13 35 79 160 302 554 1015 1865 3399 6061 10475 17470 28096 43628 65555 95551 135425 187047 252247 332684 429682
|
||||
13 6 -9 -20 11 156 538 1364 2981 5967 11279 20495 36207 62647 106658 179157 297277 487420 789503 1262734 1993315
|
||||
14 11 18 51 141 348 790 1714 3660 7803 16602 34939 71995 144184 279550 524126 950858 1671811 2854498 4743307 7687145
|
||||
2 7 22 56 123 242 437 737 1176 1793 2632 3742 5177 6996 9263 12047 15422 19467 24266 29908 36487
|
||||
19 34 68 128 220 349 519 733 993 1300 1654 2054 2498 2983 3505 4059 4639 5238 5848 6460 7064
|
||||
21 48 85 132 195 292 468 836 1684 3739 8772 20876 48964 111327 243473 510946 1029407 1994954 3728471 6738732 11810049
|
||||
11 27 55 108 210 394 696 1143 1733 2405 2997 3190 2436 -132 -5810 -16455 -34641 -63841 -108637 -174960 -270362
|
||||
12 12 12 25 90 292 791 1869 4012 8064 15537 29266 54829 103647 199701 393835 793523 1623291 3344337 6885726 14081159
|
||||
5 13 31 72 164 358 736 1410 2499 4070 6039 8076 9700 11088 15835 38309 120943 371965 1044017 2693426 6497234
|
||||
-1 -4 4 46 162 411 867 1607 2698 4206 6273 9338 14615 24985 46510 90835 178809 345728 648682 1176574 2063472
|
||||
8 16 23 40 92 216 455 847 1408 2108 2839 3374 3316 2036 -1401 -8323 -20552 -40520 -71401 -117260 -183220
|
||||
27 54 93 143 215 340 581 1059 2009 3892 7603 14833 28665 54510 101519 184641 327535 566586 956321 1576571 2541779
|
||||
18 25 37 63 114 201 333 515 746 1017 1309 1591 1818 1929 1845 1467 674 -679 -2763 -5777 -9950
|
||||
11 23 58 131 266 508 956 1834 3618 7240 14408 28142 53779 101035 188408 352630 668776 1292502 2547568 5104551 10339633
|
||||
20 30 55 112 230 464 919 1792 3444 6514 12092 22012 39486 70717 129039 244932 488666 1018738 2181538 4711697 10130222
|
||||
8 15 22 29 36 43 50 57 64 71 78 85 92 99 106 113 120 127 134 141 148
|
||||
8 17 18 5 -32 -110 -256 -510 -928 -1585 -2578 -4029 -6088 -8936 -12788 -17896 -24552 -33091 -43894 -57391 -74064
|
||||
0 6 28 73 155 304 573 1043 1826 3066 4938 7645 11413 16484 23107 31527 41972 54638 69672 87153 107071
|
||||
8 14 26 39 49 61 112 320 974 2687 6657 15139 32341 66134 131237 254984 487637 921079 1723959 3210704 5981290
|
||||
-3 6 32 88 209 468 1005 2092 4276 8669 17497 35106 69812 137381 267702 517614 995199 1904592 3626038 6854228 12829699
|
||||
16 14 18 32 52 64 53 40 180 979 3722 11247 29252 68383 147421 297965 571096 1046604 1845466 3146378 5207268
|
||||
0 19 60 146 330 708 1432 2721 4864 8205 13096 19800 28322 38142 47820 54439 52848 34663 -13020 -109250 -281238
|
||||
19 37 70 119 185 269 372 495 639 805 994 1207 1445 1709 2000 2319 2667 3045 3454 3895 4369
|
||||
8 18 30 51 92 174 350 764 1787 4310 10347 24225 54843 119816 252855 516572 1024178 1975442 3715028 6825207 12270294
|
||||
9 31 64 108 163 229 306 394 493 603 724 856 999 1153 1318 1494 1681 1879 2088 2308 2539
|
||||
27 36 46 65 110 223 504 1178 2725 6116 13214 27417 54640 104755 193632 345950 598975 1007532 1650430 2638633 4125506
|
||||
-3 -9 -19 -25 -9 63 252 660 1449 2882 5441 10155 19412 38768 80661 171586 365345 766697 1572457 3141343 6110353
|
||||
9 13 16 19 30 81 256 730 1819 4041 8188 15409 27304 46029 74412 116080 175597 258613 372024 524143 724882
|
||||
8 17 26 35 44 53 62 71 80 89 98 107 116 125 134 143 152 161 170 179 188
|
||||
13 29 69 150 300 564 1014 1770 3055 5340 9688 18482 36824 75023 152753 305660 595433 1124631 2057879 3651414 6293380
|
||||
19 39 64 101 169 299 534 929 1551 2479 3804 5629 8069 11251 15314 20409 26699 34359 43576 54549 67489
|
||||
26 48 79 119 168 226 293 369 454 548 651 763 884 1014 1153 1301 1458 1624 1799 1983 2176
|
||||
16 28 45 62 80 120 240 563 1330 3003 6482 13603 28310 59352 126262 272164 590489 1279633 2753130 5858989 12311553
|
||||
16 27 38 49 60 71 82 93 104 115 126 137 148 159 170 181 192 203 214 225 236
|
||||
16 26 52 107 212 412 806 1601 3204 6384 12578 24502 47411 91748 178785 352718 706597 1437520 2962583 6158201 12843931
|
||||
15 23 44 100 234 527 1138 2396 4995 10379 21457 43857 88008 172421 328611 608145 1092295 1904695 3227218 5318970 8537806
|
||||
19 35 67 125 219 359 555 817 1155 1579 2099 2725 3467 4335 5339 6489 7795 9267 10915 12749 14779
|
||||
14 9 -2 -25 -60 -96 -107 -38 250 1146 3714 10678 28555 72047 172745 395881 871826 1854119 3824278 7677249 15042442
|
||||
0 14 48 119 263 559 1175 2446 5004 10002 19512 37235 69743 128583 233715 418934 740144 1287614 2203656 3707527 6129775
|
||||
-6 -13 -11 9 54 127 233 409 798 1797 4331 10342 23629 51210 105348 206191 384454 682459 1149765 1826027 2697892
|
||||
14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6
|
||||
9 15 23 41 93 228 528 1127 2265 4422 8622 17094 34685 71869 151157 320706 682873 1452897 3076233 6455943 13379245
|
||||
26 38 54 85 154 309 648 1354 2736 5284 9786 17637 31605 57512 107535 206117 399770 772302 1467138 2718337 4891512
|
||||
7 2 -4 -11 -19 -28 -38 -49 -61 -74 -88 -103 -119 -136 -154 -173 -193 -214 -236 -259 -283
|
||||
17 40 72 120 202 355 665 1340 2867 6327 14000 30508 64985 135242 275772 552897 1092529 2128842 4085140 7700052 14210216
|
||||
-3 -4 -7 -12 -19 -28 -39 -52 -67 -84 -103 -124 -147 -172 -199 -228 -259 -292 -327 -364 -403
|
||||
9 21 38 62 99 161 268 450 749 1221 1938 2990 4487 6561 9368 13090 17937 24149 31998 41790 53867
|
||||
2 9 39 99 204 393 760 1519 3132 6545 13600 27720 54996 105835 197349 356668 625334 1064865 1763453 2843561 4469892
|
||||
20 33 49 75 125 228 457 1004 2337 5480 12453 26893 54846 105671 192927 335020 555266 880875 1340177 1957191 2742379
|
||||
18 21 16 6 5 57 270 860 2190 4774 9202 15936 24945 35235 44593 50493 54394 73951 171296 510662 1464845
|
||||
10 11 18 38 71 100 71 -142 -790 -2316 -5409 -10945 -19511 -29701 -33227 -2480 138638 579164 1757487 4641596 11293649
|
||||
25 33 43 67 138 323 742 1611 3346 6797 13731 27756 55976 111792 219447 421300 789851 1449309 2618271 4700169 8479106
|
||||
27 42 62 88 120 169 286 615 1492 3635 8492 18826 39628 79522 153115 285551 522357 951296 1749478 3279940 6279276
|
||||
-1 11 47 125 280 574 1106 2022 3525 5885 9449 14651 22022 32200 45940 64124 87771 118047 156275 203945 262724
|
||||
13 21 51 115 225 393 631 951 1365 1885 2523 3291 4201 5265 6495 7903 9501 11301 13315 15555 18033
|
||||
20 35 53 83 140 245 425 713 1148 1775 2645 3815 5348 7313 9785 12845 16580 21083 26453 32795 40220
|
||||
10 26 63 132 248 429 694 1074 1663 2751 5098 10427 22235 47044 96239 188667 354200 638496 1109225 1864062 3040786
|
||||
6 -1 -9 -15 -17 -13 13 141 635 2188 6391 16606 39556 88146 186315 377108 735668 1389501 2549183 4553679 7935653
|
||||
9 15 43 117 265 514 885 1388 2017 2745 3519 4255 4833 5092 4825 3774 1625 -1997 -7533 -15495 -26471
|
||||
7 22 41 65 106 207 489 1245 3117 7431 16845 36609 76972 157632 315649 618971 1188707 2234572 4109585 7392185 13006510
|
||||
10 9 5 -1 3 51 224 700 1840 4321 9327 18809 35825 64971 112914 189038 306214 481705 738217 1105107 1619759
|
||||
12 16 30 69 148 282 486 775 1164 1668 2302 3081 4020 5134 6438 7947 9676 11640 13854 16333 19092
|
||||
1 0 10 42 98 172 270 462 979 2368 5718 12970 27324 53756 99658 175614 296325 481696 758098 1159818 1730710
|
||||
8 19 38 73 142 283 562 1079 1973 3430 5708 9217 14739 23954 40566 72513 136014 262573 510546 983505 1858428
|
||||
9 24 57 114 205 359 643 1184 2197 4026 7209 12582 21441 35785 58667 94684 150641 236428 366153 559578 843909
|
||||
8 14 22 32 44 58 74 92 112 134 158 184 212 242 274 308 344 382 422 464 508
|
||||
24 34 44 54 64 74 84 94 104 114 124 134 144 154 164 174 184 194 204 214 224
|
||||
16 30 63 126 233 405 686 1187 2184 4316 8979 19130 40965 87415 185254 389023 807192 1649322 3307839 6494862 12463897
|
||||
-7 -7 1 32 121 335 787 1666 3321 6479 12739 25563 52073 106047 212569 414805 783321 1428197 2513885 4276266 7040633
|
||||
-2 1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58
|
||||
13 27 38 41 36 48 177 688 2156 5707 13455 29337 60698 121182 235783 449463 842011 1554867 2842648 5177133 9461476
|
||||
15 42 93 182 326 549 884 1374 2086 3178 5119 9300 19562 45721 111199 268798 632393 1439844 3177921 6832092 14389654
|
||||
7 28 73 151 265 408 559 679 707 556 109 -785 -2315 -4712 -8253 -13265 -20129 -29284 -41231 -56537 -75839
|
||||
8 5 13 42 97 177 284 446 766 1532 3473 8340 20149 47680 109278 241921 518597 1082840 2220086 4508651 9140126
|
||||
17 27 40 71 149 317 632 1165 2001 3239 4992 7387 10565 14681 19904 26417 34417 44115 55736 69519 85717
|
||||
24 37 47 65 117 257 594 1347 2963 6367 13474 28217 58615 120994 248715 510261 1046343 2144574 4386122 8926186 18016274
|
||||
11 16 36 80 158 277 445 706 1254 2711 6703 16929 40991 93338 199774 404089 777493 1431666 2536382 4342822 7213860
|
||||
0 -2 8 48 141 321 657 1303 2580 5096 9915 18799 34571 61685 107144 181982 303624 499562 812938 1310810 2096097
|
||||
4 15 39 91 211 473 995 1967 3741 7078 13740 27774 58093 123376 261026 543285 1106377 2204300 4310572 8314176 15899538
|
||||
-7 6 36 87 163 272 446 788 1568 3411 7651 16966 36460 75419 150039 287505 531891 952452 1654990 2797097 4608209
|
||||
13 29 56 95 152 244 405 692 1191 2023 3350 5381 8378 12662 18619 26706 37457 51489 69508 92315 120812
|
||||
15 27 59 125 237 417 722 1283 2361 4428 8300 15415 28528 53504 103742 210470 445527 969865 2133765 4678765 10135083
|
||||
20 31 57 122 274 596 1223 2377 4439 8101 14695 26909 50338 96812 191434 387177 794467 1639641 3377468 6902112 13932807
|
||||
10 37 91 200 416 820 1528 2716 4696 8091 14175 25464 46666 86122 157896 284700 501870 862641 1445003 2360456 3765020
|
||||
6 24 54 95 153 251 440 812 1516 2778 4926 8421 13895 22197 34448 52106 77042 111628 158838 222363 306741
|
||||
9 24 49 84 125 162 193 281 693 2172 6405 16762 39393 84782 169869 320863 576881 994560 1653801 2664816 4176661
|
||||
3 10 23 57 149 386 945 2142 4499 8866 16685 30566 55492 101260 187366 352765 675303 1309938 2562335 5026719 9836291
|
||||
15 29 55 109 226 481 1024 2134 4299 8344 15672 28779 52397 95981 178896 340733 660899 1294259 2533505 4914517 9388784
|
||||
14 33 78 166 331 644 1248 2423 4711 9165 17861 34963 68917 136884 273538 548338 1099300 2198986 4383250 8701159 17195603
|
||||
7 5 5 7 11 17 25 35 47 61 77 95 115 137 161 187 215 245 277 311 347
|
||||
0 2 9 21 38 60 87 119 156 198 245 297 354 416 483 555 632 714 801 893 990
|
||||
8 11 29 79 200 478 1087 2365 4957 10076 19965 38689 73433 136495 248086 439830 758518 1269449 2059289 3241351 4974534
|
||||
9 26 71 154 282 459 686 961 1279 1632 2009 2396 2776 3129 3432 3659 3781 3766 3579 3182 2534
|
||||
-8 -9 -1 23 70 147 261 419 628 895 1227 1631 2114 2683 3345 4107 4976 5959 7063 8295 9662
|
||||
14 38 88 183 349 621 1047 1694 2656 4064 6098 9001 13095 18799 26649 37320 51650 70666 95612 127979 169537
|
||||
1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61
|
||||
10 17 33 71 156 319 593 1016 1655 2681 4550 8393 16823 35591 76964 166498 356232 749489 1545759 3118955 6149158
|
||||
-2 5 20 55 147 378 896 1945 3924 7507 13868 25067 44665 78648 136752 234293 394618 652305 1057252 1679807 2617103
|
||||
-2 -3 -3 12 76 250 640 1443 3044 6202 12405 24581 48599 96524 193673 393656 809674 1677915 3482413 7194006 14714566
|
||||
-5 -2 2 11 40 131 388 1045 2594 6015 13162 27362 54272 103007 187497 327953 552225 896728 1406510 2133961 3135644
|
||||
-1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21
|
||||
6 23 51 90 140 201 273 356 450 555 671 798 936 1085 1245 1416 1598 1791 1995 2210 2436
|
||||
22 44 78 135 237 421 758 1410 2772 5783 12540 27421 59046 123639 250801 493519 945638 1772306 3262446 5917591 10599023
|
||||
24 37 60 106 197 375 727 1435 2867 5730 11311 21837 40990 74618 131688 225532 375442 608675 962934 1489396 2256363
|
||||
12 20 49 112 222 392 635 964 1392 1932 2597 3400 4354 5472 6767 8252 9940 11844 13977 16352 18982
|
||||
2 7 24 61 126 227 372 569 826 1151 1552 2037 2614 3291 4076 4977 6002 7159 8456 9901 11502
|
||||
12 11 22 60 158 379 821 1618 2953 5122 8728 15159 27666 53731 110255 234858 510014 1112985 2415218 5172306 10872818
|
||||
17 24 49 120 294 677 1456 2952 5715 10719 19792 36560 68444 130715 254454 501802 994701 1968430 3870295 7539464 14530122
|
||||
25 40 65 122 253 535 1117 2293 4630 9184 17861 34010 63355 115342 204806 353380 588983 939636 1414390 1959381 2372399
|
||||
25 52 90 138 195 260 332 410 493 580 670 762 855 948 1040 1130 1217 1300 1378 1450 1515
|
||||
0 2 24 87 221 468 885 1547 2550 4014 6086 8943 12795 17888 24507 32979 43676 57018 73476 93575 117897
|
||||
19 32 61 117 214 369 603 947 1457 2242 3509 5629 9228 15307 25395 41739 67535 107204 166717 253973 379234
|
||||
23 32 38 44 60 103 197 373 669 1130 1808 2762 4058 5769 7975 10763 14227 18468 23594 29720 36968
|
||||
4 11 19 35 76 180 439 1069 2539 5797 12662 26510 53500 104832 201057 380617 717363 1357502 2598934 5062820 10063437
|
||||
10 19 23 14 -24 -121 -314 -610 -897 -761 888 6598 22021 59353 144459 331532 733040 1580211 3343069 6963206 14293206
|
||||
3 17 48 105 201 354 600 1028 1847 3495 6800 13203 25053 45984 81384 138966 229451 367373 572016 868493 1288977
|
||||
-4 -3 10 49 132 289 583 1147 2252 4449 8873 17855 36050 72341 142802 274973 513588 927669 1618516 2727541 4442064
|
||||
19 39 74 133 236 422 765 1415 2696 5313 10758 22099 45557 93732 192181 392487 797276 1606233 3197558 6267150 12058959
|
||||
-7 -10 -13 -16 -19 -22 -25 -28 -31 -34 -37 -40 -43 -46 -49 -52 -55 -58 -61 -64 -67
|
||||
21 44 74 122 221 432 849 1603 2865 4848 7808 12044 17897 25748 36015 49149 65629 85956 110646 140222 175205
|
||||
18 26 39 66 116 198 321 494 726 1026 1403 1866 2424 3086 3861 4758 5786 6954 8271 9746 11388
|
||||
21 40 78 164 356 766 1605 3259 6420 12322 23187 43106 79841 148586 279840 535679 1042583 2055644 4079972 8092520 15934162
|
||||
20 37 62 95 136 185 242 307 380 461 550 647 752 865 986 1115 1252 1397 1550 1711 1880
|
||||
0 2 15 48 121 283 642 1407 2942 5832 10961 19602 33519 55081 87388 134409 201132 293726 419715 588164 809877
|
||||
8 13 15 13 15 42 131 338 755 1592 3455 8105 20256 51423 127543 303162 686530 1482119 3060047 6065853 11589253
|
||||
12 30 59 93 125 157 214 361 722 1498 2987 5640 10262 18599 34737 67942 137708 281702 566759 1101727 2048287
|
||||
-3 10 49 127 264 492 863 1464 2440 4028 6633 11078 19417 37246 79490 183510 436575 1030078 2361565 5219525 11107638
|
||||
16 33 54 90 174 378 846 1849 3867 7702 14625 26559 46299 77769 126315 199032 305122 456279 667096 955488 1343124
|
||||
19 43 88 176 343 647 1194 2198 4111 7897 15598 31482 64323 131829 269087 544536 1090317 2160903 4249054 8320480 16296305
|
||||
22 41 67 112 212 447 969 2039 4084 7808 14445 26357 48398 90840 175255 345646 688410 1366499 2675535 5132758 9613680
|
||||
12 25 47 89 162 277 445 677 984 1377 1867 2465 3182 4029 5017 6157 7460 8937 10599 12457 14522
|
||||
5 0 -7 -1 49 197 534 1225 2596 5304 10634 21018 41034 79540 154415 302881 602927 1215420 2462671 4968277 9895903
|
||||
-9 -14 -15 1 65 237 627 1430 2974 5775 10594 18507 31038 50464 80459 127293 201992 324897 538038 942790 1811370
|
||||
2 4 0 -10 -11 41 233 709 1684 3458 6430 11112 18143 28303 42527 61919 87766 121552 164972 219946 288633
|
||||
7 26 67 150 317 656 1342 2714 5434 10819 21508 42739 84695 166680 324376 622208 1174037 2177180 3967333 7105608 12513901
|
||||
12 22 38 64 119 247 532 1123 2276 4424 8309 15295 28210 53572 107038 225653 493336 1090494 2385292 5093646 10548309
|
||||
14 12 10 19 59 159 357 700 1244 2054 3204 4777 6865 9569 12999 17274 22522 28880 36494 45519 56119
|
||||
2 14 43 115 280 632 1341 2710 5286 10076 18959 35465 66244 123814 231609 433008 806986 1494370 2740499 4962479 8852304
|
||||
16 36 82 165 307 556 1007 1841 3405 6374 12066 23034 44170 84820 163047 314653 612780 1210538 2432293 4964944 10250289
|
||||
10 8 10 20 58 188 557 1451 3382 7223 14402 27147 48738 83665 137509 216252 324578 462546 619794 766166 837338
|
||||
9 22 46 85 154 288 571 1200 2601 5616 11777 23672 45407 83249 146871 252546 431725 752582 1369644 2629419 5280540
|
||||
16 20 35 87 210 449 878 1653 3133 6129 12402 25663 53593 111897 232285 477770 971150 1946550 3840269 7447123 14183748
|
||||
22 44 94 197 405 821 1643 3250 6376 12465 24392 47913 94545 187207 371116 734593 1448530 2841203 5540681 10747619 20760527
|
||||
4 15 42 101 226 487 1024 2115 4318 8768 17778 36006 72647 145461 288069 563007 1084756 2059673 3853830 7105719 12909204
|
||||
15 23 48 115 271 611 1319 2724 5371 10107 18182 31365 52075 83527 129893 196478 289911 418351 591708 821879 1122999
|
||||
7 6 17 48 107 202 341 532 783 1102 1497 1976 2547 3218 3997 4892 5911 7062 8353 9792 11387
|
||||
-4 3 25 70 153 309 619 1270 2682 5750 12268 25628 51937 101824 193553 358902 655155 1190487 2177891 4048307 7684230
|
||||
-2 4 19 40 65 112 264 766 2210 5847 14057 30979 63235 120551 215877 364424 581237 878545 1269600 1800115 2661524
|
||||
18 30 45 58 64 58 35 -10 -82 -186 -327 -510 -740 -1022 -1361 -1762 -2230 -2770 -3387 -4086 -4872
|
||||
8 20 59 143 292 523 844 1247 1700 2138 2453 2483 2000 697 -1826 -6077 -12688 -22432 -36241 -55225 -80692
|
||||
11 12 8 -7 -28 -26 65 361 1041 2360 4662 8393 14114 22514 34423 50825 72871 101892 139412 187161 247088
|
||||
6 6 19 54 113 189 264 307 272 96 -303 -1028 -2205 -3985 -6546 -10095 -14870 -21142 -29217 -39438 -52187
|
||||
26 40 63 112 222 455 906 1708 3036 5116 8278 13187 21602 38439 76677 167925 383519 874229 1941697 4162964 8603981
|
||||
12 19 31 58 110 209 412 843 1741 3551 7128 14215 28539 58216 120779 253209 531098 1103839 2256973 4519124 8840092
|
||||
14 28 47 71 102 153 266 539 1162 2462 4957 9419 16946 29043 47712 75551 115862 172768 251339 357727 499310
|
||||
19 22 38 89 208 457 958 1941 3833 7447 14380 27796 53861 104226 200137 378978 704206 1279303 2264473 3888958 6437241
|
||||
20 38 83 177 353 665 1204 2120 3650 6152 10145 16355 25767 39683 59786 88210 127616 181274 253151 348005 471485
|
||||
18 33 52 75 103 147 258 596 1573 4137 10313 24197 53757 114135 233848 466630 914030 1767831 3387708 6439669 12137157
|
||||
16 32 61 98 136 164 171 173 281 836 2678 7743 20501 51456 125378 299753 704238 1621680 3648963 8007452 17127734
|
||||
0 9 25 62 141 293 566 1037 1844 3286 6097 12096 25583 56164 124287 271914 582905 1221701 2506400 5046590 10003946
|
||||
-4 12 56 141 280 486 772 1151 1636 2240 2976 3857 4896 6106 7500 9091 10892 12916 15176 17685 20456
|
||||
134
day09/main.go
Normal file
134
day09/main.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"cmp"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||||
|
||||
type result struct {
|
||||
valuePT1 int
|
||||
valuePT2 int
|
||||
}
|
||||
|
||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
|
||||
|
||||
var log = aoc.Log
|
||||
|
||||
func run(scan *bufio.Scanner) (*result, error) {
|
||||
var histories [][]int
|
||||
var values []int
|
||||
var rvalues []int
|
||||
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
if len(text) == 0 {
|
||||
continue
|
||||
}
|
||||
histories = append(histories, aoc.ReadStringToInts(strings.Fields(text)))
|
||||
|
||||
log(last(histories...))
|
||||
|
||||
values = append(values, predictNext(last(histories...)))
|
||||
rvalues = append(rvalues, predictPrev(last(histories...)))
|
||||
}
|
||||
|
||||
log("values", values)
|
||||
log("rvalues", rvalues)
|
||||
|
||||
return &result{valuePT1: sum(values...), valuePT2: sum(rvalues...)}, nil
|
||||
}
|
||||
|
||||
func predictNext(in []int) int {
|
||||
log(" ---- PREDICT NEXT ----")
|
||||
defer log(" ----------------------")
|
||||
|
||||
history := makeHistory(in)
|
||||
|
||||
aoc.Reverse(history)
|
||||
|
||||
return predict(history, func(a, b int) int { return a + b })
|
||||
}
|
||||
|
||||
func predictPrev(in []int) int {
|
||||
log(" ---- PREDICT PREV ----")
|
||||
defer log(" ----------------------")
|
||||
|
||||
history := makeHistory(in)
|
||||
|
||||
for i := range history {
|
||||
aoc.Reverse(history[i])
|
||||
}
|
||||
aoc.Reverse(history)
|
||||
|
||||
return predict(history, func(a, b int) int { return b - a })
|
||||
}
|
||||
|
||||
func predict(history [][]int, diff func(a, b int) int) int {
|
||||
log(" ---- PREDICT ----")
|
||||
defer log(" -----------------")
|
||||
|
||||
for i := range history[1:] {
|
||||
lastHistory, curHistory := last(history[i]...), last(history[i+1]...)
|
||||
|
||||
history[i+1] = append(history[i+1], diff(lastHistory, curHistory))
|
||||
log(lastHistory, curHistory, last(history[i+1]))
|
||||
}
|
||||
|
||||
log("last", last(history...))
|
||||
return last(last(history...)...)
|
||||
}
|
||||
|
||||
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)
|
||||
log(diffs)
|
||||
|
||||
if max(diffs[0], diffs[1:]...) == 0 && min(diffs[0], diffs[1:]...) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return history
|
||||
}
|
||||
|
||||
func max[T cmp.Ordered](a T, v ...T) T {
|
||||
for _, b := range v {
|
||||
if b > a {
|
||||
a = b
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
func min[T cmp.Ordered](a T, v ...T) T {
|
||||
for _, b := range v {
|
||||
if b < a {
|
||||
a = b
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
func sum[T cmp.Ordered](v ...T) T {
|
||||
var s T
|
||||
for _, a := range v {
|
||||
s += a
|
||||
}
|
||||
return s
|
||||
}
|
||||
func last[T any](v ...T) T {
|
||||
return v[len(v)-1]
|
||||
}
|
||||
44
day09/main_test.go
Normal file
44
day09/main_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"testing"
|
||||
|
||||
"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, int(114))
|
||||
|
||||
is.Equal(result.valuePT2, 2)
|
||||
}
|
||||
|
||||
func TestInput(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
t.Log(result.valuePT1)
|
||||
is.Equal(result.valuePT1, int(1806615041))
|
||||
|
||||
t.Log(result.valuePT2)
|
||||
is.True(result.valuePT2 < 1806615046) // first attempt
|
||||
is.Equal(result.valuePT2, 1211)
|
||||
}
|
||||
5
day10/example1.txt
Normal file
5
day10/example1.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
.....
|
||||
.S-7.
|
||||
.|.|.
|
||||
.L-J.
|
||||
.....
|
||||
5
day10/example2.txt
Normal file
5
day10/example2.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
..F7.
|
||||
.FJ|.
|
||||
SJ.L7
|
||||
|F--J
|
||||
LJ...
|
||||
9
day10/example3.txt
Normal file
9
day10/example3.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
...........
|
||||
.S-------7.
|
||||
.|F-----7|.
|
||||
.||.....||.
|
||||
.||.....||.
|
||||
.|L-7.F-J|.
|
||||
.|..|.|..|.
|
||||
.L--J.L--J.
|
||||
...........
|
||||
10
day10/example4.txt
Normal file
10
day10/example4.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
.F----7F7F7F7F-7....
|
||||
.|F--7||||||||FJ....
|
||||
.||.FJ||||||||L7....
|
||||
FJL7L7LJLJ||LJ.L-7..
|
||||
L--J.L7...LJS7F-7L7.
|
||||
....F-J..F7FJ|L7L7L7
|
||||
....L7.F7||L7|.L7L7|
|
||||
.....|FJLJ|FJ|F7|.LJ
|
||||
....FJL-7.||.||||...
|
||||
....L---J.LJ.LJLJ...
|
||||
10
day10/example5.txt
Normal file
10
day10/example5.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
FF7FSF7F7F7F7F7F---7
|
||||
L|LJ||||||||||||F--J
|
||||
FL-7LJLJ||||||LJL-77
|
||||
F--JF--7||LJLJ7F7FJ-
|
||||
L---JF-JLJ.||-FJLJJ7
|
||||
|F|F-JF---7F7-L7L|7|
|
||||
|FFJF7L7F-JF7|JL---7
|
||||
7-L-JL7||F7|L7F-7F7|
|
||||
L.L7LFJ|||||FJL7||LJ
|
||||
L7JLJL-JLJLJL--JLJ.L
|
||||
140
day10/input.txt
Normal file
140
day10/input.txt
Normal file
@@ -0,0 +1,140 @@
|
||||
F---7-FJ.7--FJ7.-.7-|7F.|7FJ77F7J-|--.FLF|.F-7-F7.F.J77|--|7--|7|-J-F--7-F7.F7-F7F7F-|-|-F777L7|-.FLF|-77F7-FJF|JF--F.77J-L7-FF--7.FFF7FF7.7
|
||||
|J.F|7F|F7J.J-L-|-|.L7F7JF7-7-LJ|LJ.F7.L|.F|F7FJ7.F7.|F|L7.L7L|-F-|7|L|JFF.F||F777L|-77L-|JF7FJJJLF7LL7|.L77|L7LLLJ.|..LLL7|L7-.-JFFLL-7L-FF
|
||||
F7L7JLLJL-7FL7|F7-J7.-J.7L7J|.|-JF|FLFF7L-JLL|-F7-F|77|.|L7FJ7JJFJL7JJJFF.FJ||||JFF|LL7F-JF|.LJ7F.|F7F|J7LLL-7||||LFFFF77|-L7LL7F7-JL7|FF7L|
|
||||
JFL7FJ7.--JJ7L||.LF|7JJFLFLF7.|.LFF7-FJ|-J-77|-F.|J|LLFF-|-7JL7-J7L|JLF7-7F7|LJL-7|L7F7J-FJ|F|7|77|J-F..FJL.|F77-7F|-FJ|J7J.--7.7J.7-|-||LF|
|
||||
.|LLFJLF--J.FL|-J.F77F-77.L|L7F77F7.F|FJ7.FJ7JF7F7|F-J..7JL|..FF---|J-F|JF|||F--7|-FL7.J-J.|LFFJ-7.L7J|.7-|LJJF7L77LL||.FL--JJ|-L-F|7F-JJ|.|
|
||||
FL77J|LJFJFF7JJ|J7LJ.|.LF.LL7|||7||-FJL---7.LFJL7J7|FLF7J|F77-J|JJFJ-F-7FFJLJL-7LJ7LLLJ7JLL-7||J|||L-7|---L.FFLLFF---|F--J.|.|L.||FJ7.LLL|-J
|
||||
|L-J-JJ-F-F-J7F--7.F7F7F7FF-JLJ|FJ|JL7F-7FJ7-L7FJF-7F7||7FFF7JL7.-JLF|FJFJF7F7FJFFL-|.L-7J|FJFJ-JJ7.L|7.|7J-|J.||||LFLJ-F|F7-7|FF-L7|7-.|L7|
|
||||
7|LF|JLL|.F.F-FJF-7|||LJL7L-7F-JL7L7FJL7LJF77F|||L7||||L-7F||.7F7FLFFJL-JFJLJLJ-F|J.F-FL7.LJ||.|L.F7|.F7.7|FJ||-J|J-J7.7-7---|-LJF|7F|-77-L-
|
||||
|J.7|LF7JF|F7|L.L7|||L7F-J-F||F7FJFJ|F-JF7||F7||-F|||||F-JFJ|7J|L|F-L-7F7L-7F777.|JF77J-F7FFF777LFFF-F-7-7--LJL|-L|.FF-F.JL|.LFJ-77-F|7F77FJ
|
||||
JJ--JLJL-J|J.FLF-J|||L||F77FJ||||FJFJ|F7|||LJLJ|JFJ||||L77L7|F--7F7-F7LJ|F7|||F7F7.L|.F-JL7FJL7F---7JL7L7F7.L|F--7L-L7.J-.-7JJ|L-7L.|JFJLJF|
|
||||
|JFLJF|-77F-7.FL-7LJL-J|||FJFJ|||L7|FJ|LJ|L---7L7|FJ|LJFJ7FJLJF-J||.||F-J|LJ|LJLJ|7-J7L-7FJL7FJ|F--J--L7|||7FFF-FJ|JLL|FLFLJ.-L7FLL-|L|.7.FF
|
||||
L-77LJJ|FJ|7J.--LL----7|||L7|FJ||FJ||FJF-JF7|FJFJ|L7L7FJF7|F7FJ-FJL-J||F7L-7L7F--J.7|F-7||F7||FJL7L|-F-JLJL-7-|FJLJ77.|7.L7JF|L|7.|---|F--.F
|
||||
7JFF7||FJJJJL7J7.F-7F-JLJL-JLJFJ||7|LJFJF7|L7L7L7L7|-|L7|LJ|LJJ.L---7|LJL7FJ|||F-77LLL7||LJLJLJF-J-|LL---7F-J|||..JJF-.F7.F-7|L|7F77JFJ-L|FJ
|
||||
|-|LLJF-7LJ|LL|--L7|L7F--7F--7L-JL7L7FJFJ||FJF|FJFJ|FJFJL-7L-7F-7LF7|L7F7|L7FJ||FJF7FFJLJF-----JF-7F7F-7FJL--777-7L-|JF|77LLLL7JFJ|F-JJ.L|7|
|
||||
77LJ7F--7J7L7L|.F-J|FJ|F-J|F-JF-7FJFJL7|FJ|L7FJL-JFJ|FJF7|L7FJL7|F|||FJ|LJFJL7||L7|L7L--7L7F-7F7|FJ||L7||F---JL|-L7J.-77J-F.||JF|.L--J.--L7|
|
||||
L77--L-7J-|7LFF7L-7|L-JL-7||F7|FJL7|F-J|L-JFJL-7F7|FJL7||F-J|F-J|FJLJL7|F7L7-||L7LJFJJF7|FJL7LJLJL7||FJ||L--7F-7-|7.F.|7JL-L7J-7JFFL--JFFL.L
|
||||
..FFJL7L7-LLF7|L--JL-7F--J|LJ||L7FJ|L7F|F--JF7-LJ|||F-J||L-7LJF-JL--7FJLJ|FJFJL7|F-JF7||||F7|F----J||L7LJF--JL7|F--7LFLJ--||||FLLF7-J.FF-.F|
|
||||
F-J|7L|-77|-J7|F7F--7|L---JF-JL7|L-JFJFJL-7FJL7F7|||L7|||F7|F-JF7.F7||F7FJL7L7FJ||.FJ||LJ||LJL-7-F7||JL7FJF7F7||L-7|-FJ-7LL77-F7-F|J.F7||F-7
|
||||
LL7L77L-7-7-LLLJLJF-JL-----JF--JL--7L-JF7FJL7FJ||||L7L7|LJLJ|F7|L7||||||L-7L7||FJL-JFJL-7||F---JFJLJ|F-J|FJLJLJ|F7|L7JF7.7JL7|LF-7.F-FF77JJ.
|
||||
FF--.7.LJLL7|.|FF-JF--------JF7F7F7|F--J||F-JL-JLJ|FJFJL7F--J|LJFJ|||||L7|L7LJ||F---JF--JLJL--7JL7F-JL7FJ|F----J|||FJFJ|7JF-J-7|JL||LLLJL7-F
|
||||
7|..L-FFJJFL7FFLL-7|F---77F7FJLJLJ||L7F7LJL--7F---JL7|F7||F--JF-JFJ||||FJF7L7FJ||F--7L---7F---JF-JL7F7|L-JL7F--7|||L-JFJF7L7F7JJ.FJF-7L7J|7|
|
||||
F7.L7LJJ.FJL|F7L|7LJL7F7L-J|L----7|L7LJL7F7FFJL7F-7||||LJLJF--JF7L7||LJL7|L-JL7|LJF7|F7F-JL-7F7L7F-J|||F---J|F7||LJF--J||L7JLJ.LFLJ|LJ--7JL|
|
||||
J7-FJ.|7.|J-F7L7LF7F-J||F-7|F7FF-JL7|F--J||FJF-J|FJFJ||F7F7L--7||FJLJF-7|L---7||F-JLJ||L--7FJ|L7|L7FJLJL7F-7LJ|LJF-JF7F7L7L7||--|..|F7|LJ|F|
|
||||
|F7LF77J.LF-LJJ.FJLJF7|||FJLJL7L--7LJL7F7|||FJF7||FJFJLJ||L---J||L--7|FLJJF--J||L-7F7||FF-JL7|FJL7|L-7F-J|FJF7L-7L7FJLJL7|FJ7|F7|F.|--7-LL|7
|
||||
|L||F---F.F7LJ-FL---J||||L--7FJF7L|F--J|||||L7||||L7L-7FJL-7F-7||F7FJL7F-7L--7LJF-J|||L7L7F-J|L7FJL-7|L-7|L7||F7|FJ|F---J||F---77-|J|7L-F.L7
|
||||
-7F77JJF-|7JJ.F-F--77||LJF--JL-JL-J|F7J||||L7|||||FJF7|L7F-JL7|||||L7FJ|FJF-7L7FJF-J||FJFJL7FJFJL7F-J|F-J|FJ|||||L7|L7F7FJ||F--JJ7|.L7|F|.LJ
|
||||
.L.|L|.F-L|7|FFLL-7L7LJF7L--------7LJL-JLJ|FJ||LJ|L7|LJFJ|F7FJLJ||L-J|.||FJFJFJL-JF-J||FJF-JL7|F-JL7FJ|F7||FJLJLJFJ|FJ||L7LJ|F-7JF777.LFFJL|
|
||||
J..L.LL|J-J-|7J.LLL7L-7|L---------JF--7F7FJL7|L-7L-JL77L7LJLJF--JL7F-JFJ|L7|FJF---JF7|LJFJF7FJ|L-7FJL7||||||F----JFJL7|L-JF-J|FJ-LF77.|L||.F
|
||||
.F-.L7.|7.F7.F-7.FLL7FJL----------7L-7LJLJF7|L7FJF-7FJF7|F--7L--7FJL77L7L7|LJFJ|F7FJ|L-7|FJ|L7L--J||FJLJ||LJ|F7F7FJF-JL7F-JF7||F77.JJ-L-|-LJ
|
||||
FF|-.FFF-JJLLJL|FF--JL7F77F7F7F--7|F-JF7F7|||FJL-JFJL-JLJL-7L---JL7FJF7L7|L-7L7FJ||FJF-J||FJ7L---7L7|F--JL-7LJLJLJFJF-7||F-JLJLJ|-J7|-|F7-L7
|
||||
|L-JLLJL-J7F||.J|L---7LJL-JLJLJF7LJL7-|||||LJL7-F7|F7F---7FJF7F-7FJL7||FJ|F7|FJL7||L7L-7|||F7F7F7|FJ||F7F7FJF----7L-JFJ|||F---7FJFL7.FFJJ|F7
|
||||
..|.|F7L77LL77J|F-7F7L--------7|L--7L-JLJ|L--7|FJ||||L7F7LJ|||L7LJF-J||L7LJ||L--J||FJF-JLJ||LJLJ||L7|LJ|||L7L-7F7L--7L-JLJL7F7LJ-7F|-7.|7FLJ
|
||||
F.L|-|J.F7.|L|-LL7LJL----7F-7FJ|F-7L7F---JF7FJLJFJLJ|FJ|L--7||FJF-JF7||JL-7LJF7F-J|L7L--7FJL7F--J|FJ|F-J||FJF-J|L--7L7F7F--J|L7L|F-J|F|JLJ|J
|
||||
|F-L.|.-JL7|JF-L|L------7|L7LJFJL7|FJ|F--7||L--7|F7FJL7|F--J||L7|F-J|||F7-L-7|LJF7|FJF7FJ|F7||F7FJL-J|F7|||FJLFJF--J-|||L---JFJ.-JF|JLJ|J.JJ
|
||||
7-LJFJ7|J.F-.J77FF------JL-JF-J..||L7||F-J||FF7||||L7FJ||F7L||F||L-7|||||F7F||F7|||||||L7|||||||L7F--J||||||F7|FJF77FJ||F-7F7|F7-|FL-F.7-7J|
|
||||
F7-|7.FF-FJ-|JF7FL--7F7F7F--JF7-FJL-J|||F7||FJ|||||FJ|FJLJ|FJ|FJL7FJ||||||L7|LJLJ|||FJ|FJ||||||L7||F-7|LJLJLJLJL-JL7L7||L7||LJ|L--7J7|FL-|-F
|
||||
LJ--F7L---JFLJL-JJ-LLJLJLJF--JL7L7F77||LJLJ||JLJ||LJL|L-7.||FJL-7|||LJ||LJFJL7F--J|LJFJL7LJ||||FJ|||L||F----------7L7||L7|||F-JF--JJ-F7LLJ-J
|
||||
|.LF-JF-F|.|J7.L77|.F--7F7L---7L-J|L7|L7F--JL-7F||LF-JF7L7LJL7F-JLJF--J|F-JF-JL7F7L77L--JJFJ|||L7|LJFJ|L---------7L7||L7|||LJF7L7|7|F|L..L7J
|
||||
|7F-J7.FFLLJ|F..F7F-JF7LJL---7L---JFJL-JL--7F-JFJL7L7FJL7L-7FJL---7|F-7||F7L7F7LJ|FJF7LF--JFJ||FJL77|FJF---------J|LJL-JLJL7FJL7L--7J-J-7...
|
||||
.-J|||-|7L|7FJF7||L-7|L-7F--7|FF7F7L--7F7F-JL7FJF7|FJL-7L7FJL7F7F-J||FJ|||L7LJ|F-J|FJL7L7F7L7LJL-7|FJ|FJF--7F7F--7F-----7FFJ|JFJF--J-7.FF--F
|
||||
J7|FLJF-L7|LF7|LJL7|LJF7LJF-JL-JLJL---J||L7F7|L7|||L7F7|FJL7-LJ|L77LJ|FJ||FJF-J|F7LJF7L7|||FJ|F--J|L7|L-JF7LJLJF7LJF7F-7|FJFJ|L7|JLJF7-FJ7||
|
||||
||L7.FL|LL-L.LL7F7L7LFJ|F7L------------JL7||||-LJ|L7||||L-7L--7L7L7JFJL7LJL7L7FJ|L7FJL-J||||F7L---JJ||F--JL----SL--JLJJLJ|FJF--J|7FL-.F77.F|
|
||||
J.||F--7.J7J|-LLJL7L7L7||L---------------JLJ|L--7L7|LJ|L-7L7F-JJL7L7L7FJF--JFJL7L7|L-7F7LJLJ|L-----7LJL7F----------7F7F7|LJ7L---J777.L7LJ--|
|
||||
L-|-|..L7-|LF.LJ-LL7L7||L--------7F--7F7F77FJF-7L7||F-JF7L7|L-7.FJFJFJ|-L-7FJF-JFJ|F7LJL7F7FJF-7F-7L7F7LJF7F-7F----J|||L7.LJJFLL-7|F7JJ.||.|
|
||||
L7F-JF-F|7.F77J|-F7L7LJL7-F---7F7LJF7LJLJL7L7|-L7|||L-7|L-J|F-JFJFJFJFJF--J|LL-7|J|||F--J|||FJFJL7L7LJL--JLJFJL-----JLJFJF|..|LL7JJ-LJ-F7FJ-
|
||||
.F.|FFFF--7||F7LFJL7L7F7|FJF-7LJL7F|L-----JFJL7J||LJF-JL-7FJL7.|FJFL-JLL7F7L-7.|L7|||L---J||L7L7FJ7L7F7F-7F7L----------JJF7-.|L-.||LJ.FLJJ|.
|
||||
FJF|--JL-7||||L7L-7L7LJ||L-JFL7F7L-JFF7F7F7L-7L7|L7.L-7F7||F7L7|L-7|F---J||F-JFJFJ||L7F---JL-JFJL7F7LJLJJLJL-----7LF7F7F7|||.F-J7LJ7.7|J.L|-
|
||||
|7JL|..L||LJLJFJF7L7L7|||7F7F-J|L7F--JLJLJL-7L-J|FJF--J||||||FJ|F7|FJF7F7|||FFJFJFJ|FJL---7F--JF-J||F7-F7F------7|FJLJLJLJL-77LLF7L7-L77L.|7
|
||||
-J7.F----|F7F7L-JL7L7L-JL-JLJF7L7LJF-------7L--7|L7L7F7|||||LJL|||||FJ||||LJFJFJ7L7|L--7F-J|F7FJF-JLJL-JLJF7F--7LJL7F-------J..|JF.77LJ-J-||
|
||||
L-FFF77|-LJLJL---7|JL-7F7F7F7||FJF7L------7|F7FJ|FJ-LJ||||||7F-J||||L7LJ|L7FJFJ|F7LJLF-JL7-||LJ7L----7F---JLJF7|JF7|||F-----7.F7FF7FJ-|...||
|
||||
|7|FJL-7-F-7F7F7FJL7F-J|||||LJLJFJL-------JLJ|L7LJLF7FJ|||||FJF7|LJ|FJF-JFJL7L-7|L--7L7F7L7LJF------7|L7F----J|L-JLJL-JF-7F-J-|L-J|JL-J7.F-7
|
||||
---L7F-J7|FJ||||L-7|L--JLJ||F7F7L7F---------7L-J|F-JLJFJ||||L7|||F-J|FJF7|F-JF7|L--7L-J||FJF7|F----7|L-JL--7F7L--7F7F7FJ.|L-7-|F--J7J|LF-J-F
|
||||
L7LFJ|F7-|L-JLJL--JL7F7|F7LJ|||L7LJF----7F-7L---7L7F7FJ|||||L||||L-7|L-J||L-7|||F--JF7FJ||FJ|||F---JL------J||LF7LJLJLJF7L7FJFJL-7LF-7LL7FF7
|
||||
FL-L7|||F|F7F-7F7F-7LJL-J|7FJ||FJF7L---7|L7|F7F-J.|||L-7|||L7|||L7FJL-7FJ|F-J|||L7F7|LJFJLJFJLJL7F7F--7F----JL-JL----7L|L7LJFJF--J7|FJ.LLLLJ
|
||||
LLF-JLJL-J|LJFJ|||FL-7F-7L7L7LJL-JL----JL7|LJLJF-7LJL7FJ|||FJ||L-J|F--J|FJL7FJ|L7||||F-JF7FJLFF7LJLJF7||F------------JFJFJF7L7|JFLFF|J.L|7L|
|
||||
F-L---7F7FJF7L7|||F--JL7L7L-JF-7F7F--7F7FJL---7|FJF7FJ||LJ|L7LJJF7|L--7||7F|L7L7||||||F7|||F7FJL-7JFJLJ|L-----7F7LF7F7L7L7|L7|L77FF7|LF.F--|
|
||||
L77LJLLJ||FJL-J||||F---J||F-7|FLJLJF-J||L7F--7LJL-J|L7|F-7|FJF--JLJF7FJ|L7FJFJFJ|LJ|||||||LJ||F-7L-JF-7|LF7F7FJ|L-JLJL7|FJ|FJ|FJFLF7F7|L.FL|
|
||||
F-LJFLLFJ|L-7F7|||LJF----JL7||F----JF7|L7|L-7|F---7L7|LJFJ|L7|F7F--J||-L7|L7L7|FJF-J|||LJ|F-JLJ||F-7L7||FJLJLJJ|F--7F-J|L-JL-J|F7F|LJL7FFLJJ
|
||||
||LFJ-LL7L7FJ|||LJFFJF7F7F7||||F-7F7|||FJL-7||L--7L-JL--J.L-J|||L--7|L-7|L7|FJLJJ|F7|||F-JL7F---J|FJFJLJL------JL7FJL--JF----7LJL-JF7FJJJJJ|
|
||||
F7|JFF|.L-JL7|LJ7F7L-J||LJ||LJLJFLJLJLJ|FF7LJL---JF-----77L-FJ|L7F7||F7|L7|||JFF-J|||LJ|F--JL----JL7L7LF7F7F-7F7FJL-----J.F-7L-7F7FJLJJJ..|J
|
||||
|L--|FFF---7||F--JL---J|F-J|F-7F7F-----JFJL7F--7F7|F---7L7|||FJFLJ||||LJ|LJLJ77L-7|LJF7LJF--7LF7F77L-JFJLJLJ.LJLJF7F-7F--7|FJF7LJLJJ|J-7-7..
|
||||
J|LF-7.L--7LJ||F7F7F-7FJL--JL7|||L---7F7|F-J|F7LJLJ|F7LL7L7-||.J|LLJLJ7.-JJLFF---J|F-JL--JF7L-J|||F--7L----7F7F--JLJFJ|F-J|L-JL-7JJJ|JF7JFJ7
|
||||
|F-JF-JL|FJF-J||LJLJFJL7.F7F-JLJL-7F7LJLJ|F7||L---7LJL7JL-J7LJ7.FF|-J--7LF-7-L-7F7|L--7F7FJL7F7LJ|L7FJJF---J|LJF7F7FJF|L--JF---7L77FF7JJFFJJ
|
||||
LL7.LJ|FFJFJF-J|F---JF7|FJ|L-7F7F7LJL---7LJ||L---7L--7L---7-..F-F|.LJ7LL.7J||LLLJ|L--7||LJF7LJ|F7L-JL--JF---JF7||||L--JF--7L-7|L7L-7||J.J.77
|
||||
J..F|.|LL7|JL-7|L----JLJ|FJF-J|||L-----7L7FJ|F---JF-7|F---J-F|..L|L.|L..F|-||F7F-JF7FJLJF-JL-7LJL--7F---JF---JLJLJL7F7FJF7L-7L-7|F7LJ|JL.7L-
|
||||
.FF-J.|FJ||J.F||F-----7L||FJF-JLJF--7F7L7|L-JL----JFJ|L-77JL7J--J|FFF7|.L|-|-F-|F-J||F-7L---7|JF7F7LJF7F7L-----7F7-||LJ7|L-7|F-JLJ|F-J|.FL-J
|
||||
FF|-7.-JFLJ.FLLJL----7L-JLJFJ|F-7L-7LJL-J|F-7F-7F7FJ-L-7L-7J|...F7F7|FL7-JJL7J|LJJ|LJL7L-7F7||FJLJL--JLJL-----7LJL7|L---JF-J|L--7||L7J7--JJ|
|
||||
L-7--JLLJL|.J.F77F7F-JF7F--JF-JFJF7L----7|L7LJFJ|LJF7F7L--J-L.|.FJ|L77..7J.FF.FLJ.J7.|L-7LJLJ|L7F7F--7F------7|F--J|F-7F7L-7L---J-L-JJ|-7.F7
|
||||
FL77L||.F--J-FJL-JLJF7|||F--JF7L-JL-----J|FJF7L-JF-J||L-7J.LL7L-JL..L-J7..JFLF-|FJ.|.F7FJF7F7L7LJ||F-J|F--7F-JLJF7LLJFJ||F7L7F7||7||.L--7.-7
|
||||
JJL7-77.JJLJ.L7F---7|LJLJL---JL---------7|L-JL7-FJF-J|F-J.|.|L-|FL--77|7F7F7||.|7F-F-J|L-JLJL7|F7LJL-7||F7LJF7F7||F-7|FJ||L7LJL-7-7-7-L7J-L|
|
||||
|.-7L||-J--JFFLJF--J|F--------------7F--JL7F-7L7|FJF7||F-7F-77FJ7J|7JF7JJFL-7J-7F77|F7L------JLJL7JF7LJLJL--JLJLJLJFJLJ-LJFJF7F-J.|||..L-..F
|
||||
77|J.LF-J|.|LFF7L--7|L---7F7F-7F7F-7LJF7F7LJFL7LJL7|||LJFJ|FJF7|L777JFJ|FL7F|7..L|-LJL-7F------7FJFJL7F-7F-7F------JF7F--7L-J|L7J77F7-|.||FJ
|
||||
LFL-77|.F7-FF7||JF7LJ7F77LJLJLLJLJ|L--JLJL7F-7L---J|||F-JFJL-J|J.JLJJ|||F|JLJF-JLJ7L7|FLJ7F----JL-JF-JL7LJJLJ|F7F---JLJF-JJF7L-J-7-7F7FL7.FL
|
||||
FF|7|FL|--F-JLJ|FJL---J|F7F7.F------------J|FJ.F--7||||F7L7F--J7F7F7F-L-77FFJJJJFLL7|JFF-7L-7F7F7F7L-77L-7F7F7|LJF-----JF7FJL7F-77J|-F|7|FJJ
|
||||
||L|--.JJ|L---7LJF7F--7LJLJL7L---------7FF7|L7FJF-J||||||.|L--77.|LL7-J-7--|||-F|||-.L|L7|F7LJLJ|||F7L-77LJLJLJF7|7F7-F7|||F-J|FJF7LF-|F7J7.
|
||||
-LJ||.LL7F|JLLL--JLJ7FJF-7F7L7F--------JFJLJFJL7|JFJLJLJL-JF--JJ7L-7J-|-FJ..|7.-|F|77|F-J|||F7F-J||||F7L7F--7F7||L-JL-JLJLJL--JL-JL7|LJ-J.L7
|
||||
|F-|-J.FF7L7F||F7F---JFJFLJ|FJL7F--7F7F7|F--JF7|L-JF--7F7F-JJJL-JF|--.7L|.7FL--.L|FF-7L-7LJLJ|L--JLJLJL7|L-7|||||F--------7F----7F-J-FLJ-7-|
|
||||
F7||-F-F-JJF7-FJLJF--7L7F--JL7JLJF7LJLJ|||-F7|LJF-7L-7|||L-7.7JFLFJ-7FJ7|7L7--LF7F7L7L-7L---7|F7F--7F--JL--JLJLJLJF---7LF7LJF7F7||F77JF-7-F7
|
||||
7JF|.L--7J7F7-L--7|F-JFJL--7FJF7F||F---J|L7|LJF-JFL--JLJL--JF7.|J|.|F7F7JFJL|.F||||-|F-J|F--JLJ||F7|L--7F---7F7F7FL-7FJFJL--JLJ|LJ||F7FL7JJ|
|
||||
..F--77JJFFFJJ|.LLJL--JF---JL-JL-JLJF7F-JFJ|F7L--------7F7F7|L7JFLFLJL7L-F--LF-J|||FJL-7FJF7F-7|LJ||F7JLJF--J|LJL7F-JL-JF7F7F-7L--JLJL7FJJF-
|
||||
L7|L|LJ.77F77LF7F---7F7L--7F7F-7F---J||F7|J||L-------7FJ|LJLJFJFF-L7JF7FL|.LLL-7LJ|L--7|L-JLJL||F7||||F--JF7FJF7FJ|F---7|||LJF|F-7F--7|-J.LJ
|
||||
.F|7|L-F--|L7FJ|L--7||L--7LJLJ7LJF---J||LJFJL-------7LJFJF7F-J.L77LJ.-77-LJ..|7L7FJF--JL-7F7JFJLJLJ|||L---JLJFJLJ-||F-7|||L--7LJ-LJJLLJJF7-F
|
||||
FF.JJ7|LJ-L7|L7|F7FJ||F-7L-------JF7|FJL--JF-7F--7F7L7FJFJLJJF7JJL|J77.F7JFFF-7FJL7L----7LJL7L----7||L-------J|F7FJLJFJLJL7F7|.F7F7|.||.---J
|
||||
FJ-|7F-7F|L|L-J|||L7|LJFJF7F7F7F-7|L-JF7F-7|FJL-7LJL-JL7L7F--JL-7.77F7-|J|FJ|FJL7FJF---7L--7L-7F7FJLJF-7F7F-7F7|||F--JF--7LJ|L-JLJL7-777-|-7
|
||||
|J-77|J|F7JL7F7LJL-JL7.L-JLJLJLJJLJF--JLJ|LJL7F7L7F7-F-JFJL7F---JF7FJL--7F7FJ|F7|L7L--7|F7FJF7LJLJF-7|FJ|||FJ||||||.F7L7FJF7L7F7F7FJ.J..F||F
|
||||
|LFJFJ7LF--FJ||F7F-7FJF7F7F-7F-----JF7F7F-7F7||L7LJL7L7FJF7|L-7F7|LJF7F-J||L7LJLJFJF7J|LJLJFJ|F7F7|.LJL-JLJL-JLJLJL-JL7|L-JL7LJ||LJLF.FF7LL|
|
||||
|-7F|JF.LL.L7|LJLJFJL-JLJ|L7|L------JLJ|L7LJ|LJLL---JFJL7|||F-J|||F-JLJF7||LL--7FJFJL7|F7F7L7||||LJF7F7F7F7F7F-7F7F7F7LJF7F7L7FJL7F--7-.|7|F
|
||||
J||FF7..-7FLLJF---JF----7L-JL----------JFJF7L------7FL7FJ||||F7|LJL-7F7||||F7F-JL7L7FJLJLJ|FJLJLJ.FJLJLJLJLJ||F|||||||F7|LJ|FJL-7LJF-JFF7JF-
|
||||
J-|L--|7LL7J|-L----JF--7L------------7F-JFJL7F-7F--JF7|L7|LJ||||F---J|||LJ|||L7F7L7|L-7F7|LJF-----JF-7F----7|L7LJ||LJ|||L-7||F-7|F7|7.LJJ7||
|
||||
||JLJ7|F.|J.F-F-----JF7L-------------J|F-JF7LJJ||F-7|||FJ|F-J|||L7F-7||L7FJ||-||L7||F-J||F7JL-7F7F7|FJ|LF--JL7L-7|L-7LJ|F-J|LJFJ|||L-7.FJJ7L
|
||||
FF7-7|F7FF77.FL--7F7FJL7F------7F--7F7|L--JL--7||L7|||||F|L7FJ||FJ|FJ|L-J|FJL7||FJ||L-7|LJL--7LJLJLJL7L7L-7F7L--JL--JF7LJF7L7FJL|||F-J-F|FFJ
|
||||
F-J-7-7||-L7-F--7LJ|L-7||F-----J|F7LJLJF--7F--J||FJ||||L7|FJL7LJL7|L-JF--JL7FJLJL7LJF-JL---7FJLF-7F--JFJF-J|L--------JL--JL7|L-7LJLJJJJLL-7|
|
||||
77F.|LFJJL-|JL-7|F7L--J||L------J||F7F7L-7LJF77||L7||LJFJ||F7|F--J|F--JF-7||L--77L-7L7F-7F7||F-JFJL--7L7L--JF--------------JL--J-|JJ|-FJJ.FJ
|
||||
|L-.LF-J7JF7-F-JLJ|F--7LJF--7F7|FJLJ|||F7L7-|L7LJFJLJF7|FJ||LJL---JL--7L7|FJF--JF--JFJL7LJ||||F-J|F-7L-JF---JF7F----7|F7LF--7.F7F|J.|7L77-L7
|
||||
J-J7.LJL--F--JF--7|L7FJF7L-7|||FJF-7LJLJL7L7|FJF7|F--J||L7||F---------JFJ|L7|LF7L--7|F7L-7LJ||L--7L7L-7|L----JLJF---JFJL-JF-JFJL7--F7|LJL77|
|
||||
L-J777-F|LL---JF-J|FJL7||F-JLJLJFJ.L----7L-J|L7|LJL--7LJJ||||F--7F7.F7FL7|FJL7||F7FJLJ|F-JF7|L-7FJFJF7L----7F---JF7JFJF-7FJF7L7FJLFJ|7JLFFFL
|
||||
FFJFFJ7-F.|FF--JF7|L7FJ||L---7F7|F7F----JJF7L7|L7F---JF-7||||L7FJ|L7||F7|||F-J|LJ|L-7FJL--J||F7||JL-JL----7|L----JL7|FJ|LJ7||FJL-7L7|--77FJ.
|
||||
FJ-LL.L7F--7|F--J||FJ|.|L----J|LJ|LJ|F7-F7||FJ|FJL-7F7L7LJLJL7|L7L7LJ||||||L-7|F7|F7||F7F--J||||L7F-7F7F7FJL7F--7F7LJL77F-7|||F--J-||J-JF7L.
|
||||
|F-F7FFLL7|F||F--J|L7L7L-----7L7FJF--JL7|||LJFJL7F-J|L7L7F-7FJL7|FJF-J|LJLJF-JLJ||||||||L7F7||||FJL7LJLJLJF-JL7.|||F-7L7L7LJLJ|F7F7||J|FL7J7
|
||||
F7J.L7|-JLLLLJL7F7L-JFJF7F7F-JFJL-JF---J|||F7L--J|F7|FJ|LJFJ|7FJ||FJF-JF---JF-7FJ||||LJ|FLJ|||LJL7FJF7F--7L--7L7LJLJ.L7L7|F---J||||||F-7.7J|
|
||||
LJ-F-FJJ--J-L|LLJL7F7L-J||||F7|F---JF7F7||LJL-7F7||||L7-F7L7L7L7|||J|F-J-F7FJFJL7|||L7FJF7FJ||F--JL-JLJF7L--7L7L-----7L7LJL-7F7|||||||FJ7L7.
|
||||
LFFF7JF-7J|-FJ-F--J||F-7LJ|LJLJL----JLJLJ|F7F7||LJ|LJFJFJ|.L7L7||||FJL7F7|||FJF-J||L7|L7||L7LJ|.F-7-F--JL---JFJF-7F--J|L7F--J|||LJLJLJL-7L||
|
||||
.|J.77|F7F-.|--L-7FJLJJL-7|F7F7F--------7||LJ|||F7L7FJ-|FJF7L7LJ|||L-7LJ|||||FL-7||FJ|FJ||-L-7L7L7L7L----7.F7L-J7LJLF7-FJL---JLJF7F-7F7FJ.L-
|
||||
F.|7|-F|F--|.L|F-J|F7F-7FJLJLJLJF---7F-7LJL-7||LJ|FJ|F7||FJL7L-7|||F-JF-J|||L7F7|||L7|L7||F7FJFJFJFJLF--7L-JL-------JL7L-7F---7FJLJ.LJLJ|FF|
|
||||
|7L-J.LJ7J||-FFJF-J||L7|L-7F7F7FJF--J|FJF7F7|||F-J|FJ||||L7FJF7||||L7FJF7||L7||||||FJL7|||||L7|LL7|F7L7FJF-------7F7F7L7-||F-7LJF-7F77LL|7-F
|
||||
FFL7|FFJLF|.|L|FJF-JL-JL--J||||||L--7||FJ|||||||F-J|FJ||L7|L7|LJLJL7|L7|||L7|||||||L7FJ||||L7||F7||||FJ|FJF----7.LJ||L-JFJLJFJ|FJFJ||7LL|J.7
|
||||
F|L|-|7J-J|FL7LJ7L--------7|LJLJF7F7|||L7||||||||F-J|-||FJL7|L-7F--J|FJ|LJFJ||||||L7||FJ|||FJ|LJ|||||L7|L-JF--7L--7|L7F7|F-7L--JFJL|L7F-LJ-F
|
||||
F--..L7...F7L|J.FF---7F7F-J|F---JLJLJ||FJ||LJ|||||F7L7LJL7FJ|F7|L7F7|L7L7LL-J||||L7|LJ|FJ||L7L-7LJ|||FJ|F-7L-7L---JL7LJ|||FJF7F7L7||FJ-7|7.|
|
||||
7J|F7JL77-FJJ|.-JL--7LJLJF7|L------7FJ|L7|L7FJ|LJ||L7L-7F|L7||||FJ|||FJFJF--7LJ|L7|L-7|L7||FJF7L7L|||L7|L7L-7L-----7|F7|||L7|LJL7L-J|J-L.F-F
|
||||
7-J-7-FF-7LJ.F-F7JF-JF7F7|LJ-F-7F7FJL7L7||FJL7L77LJFJF7L7L7|LJ|||FJLJL7L-JF7L7FJFJL7FJ|FJ||L7||FJFJ|L7||FJF-JF7F---JLJLJ|L7|L--7L7F7L-7-FJFF
|
||||
L|.|LFFJ|F|JF|LLF-JF7|||LJLF7L7LJLJF7L7LJLJF7|FJF--JFJ|FJFJL-7||||F---JF-7||FJL7L-7||FJL7||FJ|||-L7L7LJ||7|F-J||LF7F7F7J|FJL7F-JF||L--J7F7..
|
||||
FL|F-J.FF-||-77JL-7|LJLJ7F-J|FJF7F7|L7L---7|||L7L7F7L7||FJF-7|||LJL7F7FJFJ|||F7|F-JLJ|F7|||L-JLJF-JFJF-JL7LJF-JL-JLJ||L7LJF7|L--7|L-77-7|.F7
|
||||
7J.FLF--JLL|F7-F-7LJF7-F7L-7LJFJLJLJFJF7F7LJ|L7L7LJ|FJ||L7L7LJ||7F-J||L7|FJ|LJ||L---7||LJ|L-7F--JF7L7L-7FJF-JF--7F-7LJFJF7||L---JL7FJ7|||-||
|
||||
|FLL7J||L|FJ7|.L7L--JL-JL-7|F7L7F--7L7||||F7L7|FJF-JL7LJ7L7L7FJL7|F7||FJ|L7|F7|L7F7FJLJF-JF-JL7F7||FJ7FJL7|F-JF-J|7|F-J7|LJL---7JLLJ..FLL--L
|
||||
JJ|.|F|FFL|FLL-LL--------7|LJL7LJF-J-LJ||||L7||L7L7F7L-7F7|FJL7FJLJ|||||L7||||L7||LJF7LL--JF7-||LJ|L-7L7FJ|L-7|F7L7||F--JF-7F7FJJ|J-F7--J777
|
||||
FLJ.LLJJ7L|7.LF7F7F------JL---JF7L-7|F-J|LJF|||FJFJ||F7||LJL7FJ|F--J||L-7LJLJ|FJ|L--JL7F---J|FJL-7|F7|-LJFJF7||||FJ|LJF7FJ||||L7FL-F|L|F7L-L
|
||||
LJL|.FL.|LL.FF|LJLJF7F7F7F---7FJL-7|FJF7L--7|||L7|FJ||LJ|F7FJL7|L--7||F7L7F--JL7L7F-7FJL7F-7LJF--J|||L--7L7|LJ|||L7|F7||L-7LJL-J-||FJFJL-JLL
|
||||
|J-|JJ|-F7|LFFJF7F7|||||||F7F|L--7|||FJ|F--J||L7||L7|L7FJ|||.FJ|F--J||||FJL--7FJFJL7LJ.FJL7|F7L--7||L7F-JL|L-7||L7||||||F7L----7|L|.F||F7||J
|
||||
|.|F7JL7|FFJFJFJLJLJ||LJLJ|L-JF7FJLJ||F|L--7||FJ|L7||FJ|FJ|L7|FJL--7|LJ||F7F7||JL-7L-7FJF-J||L7F-J||F|L--7|F7|||FJ|||LJ|||F---7|J.-7.F7.F7|.
|
||||
F7-LL.LJLJL7L-JF7F--J|F---JF7FJ||F7-LJFJF-7||||FJFLJ||-|L7L7|LJF---JL-7|||LJLJL7F7|F7||FJ.FJL7|L7FJ|FJF--JLJ||||L7||L-7LJ|L--7LJJ7LL7L7FFJ-J
|
||||
.|JJL7.7|FFLF--JLJF7FJL-7F-J||L||||F--JFJJ||||||F---JL7L7L7||F7|F-7F7FJ||L-7F7FJ||LJLJ||F-JF-JL7||FJL7L----7||||FJ||F-JF-JF-7L-7.|7.|-|FJ.L.
|
||||
|..FFLLJF7JJ|F-7F-J|L7F-J|F-JL7LJ|LJF7FJF-J|LJ||L7F7F7L7L-JLJ|LJ|FJ||L7|L7LLJ|L-JL7F-7|||F7|F--J|LJF7L7F7F-J||LJL7||L-7|F7L7|F-J7LF.|.|7|J|L
|
||||
|J77L-JL|L|7LJLLJFFJFJL--JL7F7L7FJF7||L7|F7L-7LJ-||||L7L---7JL7FJL7|L7||FJF--JF--7LJFJLJLJ||L--7L-7|L-J||L-7|L-7FJ|L7FJLJ|FJ|L-77JJF7JL7|-7|
|
||||
7.FL7J|...J7.J-LL-L7|JLFF--J||FJL7|||L-J||L7FJ7F-J||L7L-7F-JF-JL7.||FJ|||FJF-7L-7|F7L-7-F-J|F--JF-J|F7FJ|F-J|F-JL7L7||F|||L7L-7|--FFJLF|7LL|
|
||||
L-L7L-JJ7.LFJ|.LJFLLJJJFJF7FJ|L7FLJ|L7F-JL7|L-7L7FJL-JFFJL7FJF-7L7|||FJ||L7|-L7FJLJL-7L7|F7|L--7L-7|||L7LJF7LJJ|L|FJLJ-L-L7L7.LJJF.||F|F77FJ
|
||||
7|||L|-||..||-.77LF-F--JFJ|L7L7|F--JFJL--7|L7FJFJL-7F--JF-JL7|7L-JLJ||LLJFJ|F-JL----7|FJLJ||F--JF7|||L7L--J|FJJ-LLJJJ|.L--L7|J.LJF-7FJJLL7||
|
||||
.-JLFJF7L7.F|7|-7|LFJF-7|FJFJ-LJL7F7L7.F7LJFLJFJF7FJL7F7L--7LJ77LF--JL-7FJFJL-7F7F7FJ|L-7FJ||F7FJ|||L7L7F--JJ|.FLJ-JF--.LJFLJ|.LF-L|JLL|FJJ-
|
||||
FJ7F7JL|JL-LJ-L7FF-L7|FJ|L7|J-|F-J|L7L-JL7L|7.|FJ||F-J|L7F7L-7JFFJF-7F7||FJJF-J||||L7|F-J|FJLJ|L7||L7|FJL7|J7L77.|LF|JF-7F|JL7JFL7||F|F.L-|.
|
||||
F-|JJ7.JJ-|F77-LLJJ-LJL-JLLJJJFJF7|FJF---J-||7LJ-LJ|F7L7LJ|F7|F-JFJFJ|||||F-JF7|||L7||L7-||-F-JFJLJ-|||F-J-77|L--L-L|.|-F|.LLJL|.7FF7L7J--F7
|
||||
LF-.|FL-F-F|7.LFJ-|.|7|L|7J77|L7|LJL7L---7-7|FJJJ.FLJ|FJ.LLJ||L7FJLL7|||||L-7|LJLJ.||L-J-LJ-L--J7|J-||LJJL7|LF7||.LLL7J-F|-J.7-F--FJL7|F7JLF
|
||||
F-.F||..LFJLL7FJ.F|-7-77FL.JFFLLJ-F7|F---J.||7J|.F7.LLJ-7-L7LJ-|L7-LLJLJ|||F|L----7LJ7F7JLL.LJ.LFJ|.LJJL--.|-F7-77.F7J|FL|JF7JF|LJLJFJL-F.FF
|
||||
F-F||-7-FLF7JFLJ7F|-JJ.LJJJ|-JJ|JF|LJ|F7LJ-JL77-F7JFJLL7FJ.F7.LL-J7LJJJL||F-JF7F-7L---J|LFJ-.J7JJ7L||..LL-JJ7J|F||FFF.LF.|.|L-LF-JFFLJ-FJ-J|
|
||||
L7J||.L-JLLJ--7.FL-7||.F|-L7.|.|-FJF7LJ|..7-LFJ.|L7L-||L|7-|-L.|.|L|.FF7LJL7FJLJJ|F----J.|7L|--7.|.LJ-7..|JF7|L-L-7F--L|FJ7|FLL|FJ7|-7.|-|JL
|
||||
FL7F||.||7L-F--|JF-.-F-JLF7J||L..L7||F-J7J.-.|.FL|J-FLF.|J7JFL-|-7.--F|L---JL7LF-JL--7|JF-7L7.L-FJ7|LJ7F77JJ.|JL|.-LL.|L-L-|-7.||.L7-F-7.|JL
|
||||
L|7-FLJ--F77|-LJ.|--JJJL.|JLJFJF7-LJLJ-F|7L.FJ-77J..F-|-|J|F7.|LLL-7|LL--7F7FJ.L-7F--J7F7F7-JJ.LJ--FJL|FF-7LF|7.L7FFJ-J|.L.|.LFL7.LJFJFF-|..
|
||||
.|..|.|7L.L|J.LL-L-7F7-LFJ|.FF.F7.J.|L--|7.|--7|F7FJJ.|L|-L7|--JF|.|-7F|LLJ|L77LFLJ-J.J-.JJ.|||FJF|J..|-LJF-L|7L|-7L|7L7J-JJ.L-J-||-|-LJ|LLF
|
||||
LJ-F---J.F7|77JFL-||-F7||-J-LJ-FJLJF-7|F|F-JFFJ|.F--7-LJ|LFL|-7||JFF-|LF.JL|FJ7FFJL7J-|7L77F|FFJJ|7..LL-J.777F7F|JF-77J|LFFF77FL|LL-|-.LJJJ|
|
||||
.|JF|-L|.J7LJJ77|F7|7F--|-|JL7-L7LFFJ-77-J|F-JFJ7JF|J|7|F-|7|-L|||F7.|L7-F|LJJ7-|7.|FLLF7LL-FFJ|.-L--7.LF||F-J.L|F7.L7F7.F7LLJ7J|F|-|J|L|L77
|
||||
F-7|L77L..F-J7F---7J7||.|-F.LL7.|F7.JL|F7LF|-FF-LF7|-7-|.L--|...FL|L-JFF-J-.|.7F||JF||.FL7L.7||L7JJ-7FF-7|F|-|-LF--J7L7LL7JL||LF|F--LJ|-FJ|7
|
||||
L|L--JJJ-LLJ-FF.JJLLJ7-L7-JLJJ|-.F7..-|LJ.FJ.|J..L7J.L-.--JL|.-FJ-L-LL.|.JJ-FJ.F|JLLJF-7J7JJJ|7JLJ..FL--JJ-77L7.|JLL-JL-L.LL-|7-L|J.LLL-L-|.
|
||||
331
day10/main.go
Normal file
331
day10/main.go
Normal file
@@ -0,0 +1,331 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"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) {
|
||||
m := &Path{s: -1}
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
_ = text
|
||||
|
||||
m.readLine(text)
|
||||
}
|
||||
dist := m.buildPath()
|
||||
// log(m)
|
||||
|
||||
r := &Region{List: m.List, w: m.w, l: len(m.m)}
|
||||
count := r.Count()
|
||||
|
||||
return &result{valuePT1: dist, valuePT2: count}, nil
|
||||
}
|
||||
|
||||
type node struct {
|
||||
value rune
|
||||
pos int
|
||||
whence int8
|
||||
left *node
|
||||
}
|
||||
|
||||
func (n *node) add(a *node) *node {
|
||||
if a == nil {
|
||||
return n
|
||||
}
|
||||
n.left = a
|
||||
return a
|
||||
}
|
||||
|
||||
func (n *node) String() string {
|
||||
if n == nil {
|
||||
return "EOL"
|
||||
}
|
||||
return fmt.Sprintf("node %s from %s", string(n.value), enum(n.whence))
|
||||
}
|
||||
|
||||
type List struct {
|
||||
head *node
|
||||
n *node
|
||||
p map[int]*node
|
||||
}
|
||||
|
||||
func NewList(a *node) *List {
|
||||
lis := &List{
|
||||
head: a,
|
||||
n: a,
|
||||
p: make(map[int]*node),
|
||||
}
|
||||
lis.add(a)
|
||||
|
||||
return lis
|
||||
}
|
||||
func (l *List) add(a *node) {
|
||||
l.n = l.n.add(a)
|
||||
l.p[a.pos] = a
|
||||
}
|
||||
|
||||
type Path struct {
|
||||
m []rune
|
||||
w int
|
||||
s int
|
||||
|
||||
*List
|
||||
}
|
||||
|
||||
func (m *Path) String() string {
|
||||
var buf strings.Builder
|
||||
n := m.head
|
||||
|
||||
buf.WriteString(fmt.Sprintf("head %d", len(m.p)))
|
||||
for n != nil {
|
||||
buf.WriteString("\n ")
|
||||
buf.WriteString(n.String())
|
||||
n = n.left
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
func (m *Path) readLine(text string) {
|
||||
if m.w == 0 {
|
||||
m.w = len(text)
|
||||
}
|
||||
if m.s == -1 {
|
||||
if i := strings.IndexRune(text, 'S'); i != -1 {
|
||||
m.s = i + len(m.m)
|
||||
}
|
||||
}
|
||||
|
||||
m.m = append(m.m, []rune(text)...)
|
||||
}
|
||||
func (m *Path) buildPath() int {
|
||||
m.start()
|
||||
for m.next() {
|
||||
}
|
||||
return (len(m.p) + 1) / 2
|
||||
}
|
||||
func (m *Path) start() {
|
||||
m.List = NewList(&node{value: 'S', pos: m.s})
|
||||
|
||||
switch {
|
||||
case m.peek(UP) != nil:
|
||||
m.add(m.peek(UP))
|
||||
case m.peek(DN) != nil:
|
||||
m.add(m.peek(DN))
|
||||
case m.peek(LF) != nil:
|
||||
m.add(m.peek(LF))
|
||||
case m.peek(RT) != nil:
|
||||
m.add(m.peek(RT))
|
||||
}
|
||||
}
|
||||
func (m *Path) next() bool {
|
||||
var n *node
|
||||
switch m.n.value {
|
||||
case '7':
|
||||
if m.n.whence == LF {
|
||||
n = m.peek(DN)
|
||||
} else {
|
||||
n = m.peek(LF)
|
||||
}
|
||||
case '|':
|
||||
if m.n.whence == UP {
|
||||
n = m.peek(DN)
|
||||
} else {
|
||||
n = m.peek(UP)
|
||||
}
|
||||
case 'F':
|
||||
if m.n.whence == RT {
|
||||
n = m.peek(DN)
|
||||
} else {
|
||||
n = m.peek(RT)
|
||||
}
|
||||
case '-':
|
||||
if m.n.whence == LF {
|
||||
n = m.peek(RT)
|
||||
} else {
|
||||
n = m.peek(LF)
|
||||
}
|
||||
case 'J':
|
||||
if m.n.whence == LF {
|
||||
n = m.peek(UP)
|
||||
} else {
|
||||
n = m.peek(LF)
|
||||
}
|
||||
case 'L':
|
||||
if m.n.whence == RT {
|
||||
n = m.peek(UP)
|
||||
} else {
|
||||
n = m.peek(RT)
|
||||
}
|
||||
}
|
||||
if n == nil {
|
||||
return false
|
||||
}
|
||||
if n.value == 'S' {
|
||||
last := n.whence
|
||||
next := m.head.left.whence
|
||||
|
||||
switch last<<4 | next {
|
||||
case UP<<4 | UP, DN<<4 | DN:
|
||||
m.head.value = '|' // UP UP, DN DN
|
||||
case LF<<4 | LF, RT<<4 | RT:
|
||||
m.head.value = '-' // LF LF, RT RT
|
||||
|
||||
case UP<<4 | RT, LF<<4 | DN:
|
||||
m.head.value = 'J' // UP RT, LT DN
|
||||
case UP<<4 | LF, RT<<4 | DN:
|
||||
m.head.value = 'L' // UP RT, RT DN
|
||||
|
||||
case DN<<4 | RT, LF<<4 | UP:
|
||||
m.head.value = '7' // DN LF, LF UP
|
||||
case RT<<4 | UP, DN<<4 | LF:
|
||||
m.head.value = 'F' // DN LF, RT UP
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
m.add(n)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
ST int8 = iota
|
||||
UP
|
||||
DN
|
||||
LF
|
||||
RT
|
||||
)
|
||||
|
||||
func enum(e int8) string {
|
||||
switch e {
|
||||
case ST:
|
||||
return "ST"
|
||||
case UP:
|
||||
return "UP"
|
||||
case DN:
|
||||
return "DN"
|
||||
case LF:
|
||||
return "LF"
|
||||
case RT:
|
||||
return "RT"
|
||||
default:
|
||||
return "XX"
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Path) peek(d int8) *node {
|
||||
switch d {
|
||||
case UP:
|
||||
x, y := toXY(m.n.pos, m.w)
|
||||
if y == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := fromXY(x, y-1, m.w)
|
||||
r := m.m[p]
|
||||
if any(r, '7', '|', 'F', 'S') {
|
||||
return &node{value: r, whence: DN, pos: p}
|
||||
}
|
||||
case DN:
|
||||
x, y := toXY(m.n.pos, m.w)
|
||||
if y == m.w {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := fromXY(x, y+1, m.w)
|
||||
r := m.m[p]
|
||||
if any(r, 'J', '|', 'L', 'S') {
|
||||
return &node{value: r, whence: UP, pos: p}
|
||||
}
|
||||
case LF:
|
||||
x, y := toXY(m.n.pos, m.w)
|
||||
if x == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := fromXY(x-1, y, m.w)
|
||||
r := m.m[p]
|
||||
if any(r, 'F', '-', 'L', 'S') {
|
||||
return &node{value: r, whence: RT, pos: p}
|
||||
}
|
||||
case RT:
|
||||
x, y := toXY(m.n.pos, m.w)
|
||||
if x == m.w {
|
||||
return nil
|
||||
}
|
||||
p := fromXY(x+1, y, m.w)
|
||||
r := m.m[p]
|
||||
if any(r, '7', '-', 'J', 'S') {
|
||||
return &node{value: r, whence: LF, pos: p}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fromXY(x, y, w int) int { return y*w + x }
|
||||
func toXY(i, w int) (int, int) {
|
||||
return i % w, i / w
|
||||
}
|
||||
func any[T comparable](n T, stack ...T) bool {
|
||||
var found bool
|
||||
for _, s := range stack {
|
||||
if n == s {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
type Region struct {
|
||||
*List
|
||||
inLoop bool
|
||||
count int
|
||||
w int
|
||||
l int
|
||||
}
|
||||
|
||||
func (r *Region) Count() int {
|
||||
for i := 0; i < r.l; i++ {
|
||||
if i%r.w == 0 {
|
||||
r.inLoop = false
|
||||
// fmt.Println(": ", i)
|
||||
}
|
||||
|
||||
a, ok := r.p[i]
|
||||
if ok && any(a.value, '|', '7', 'F', 'X') {
|
||||
r.inLoop = !r.inLoop
|
||||
// fmt.Print(string(a.value))
|
||||
continue
|
||||
}
|
||||
|
||||
if !ok && r.inLoop {
|
||||
// fmt.Print("I")
|
||||
r.count++
|
||||
continue
|
||||
}
|
||||
|
||||
if ok {
|
||||
// fmt.Print(string(a.value))
|
||||
continue
|
||||
}
|
||||
// fmt.Print(".")
|
||||
|
||||
}
|
||||
return r.count
|
||||
}
|
||||
110
day10/main_test.go
Normal file
110
day10/main_test.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"testing"
|
||||
|
||||
"github.com/matryer/is"
|
||||
)
|
||||
|
||||
//go:embed example1.txt
|
||||
var example1 []byte
|
||||
|
||||
//go:embed example2.txt
|
||||
var example2 []byte
|
||||
|
||||
//go:embed example3.txt
|
||||
var example3 []byte
|
||||
|
||||
//go:embed example4.txt
|
||||
var example4 []byte
|
||||
|
||||
//go:embed example5.txt
|
||||
var example5 []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.valuePT1)
|
||||
is.Equal(result.valuePT1, 4)
|
||||
}
|
||||
|
||||
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.valuePT1)
|
||||
is.Equal(result.valuePT1, 8)
|
||||
}
|
||||
|
||||
func TestExample3(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(example3))
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
// t.Log(result.valuePT1)
|
||||
is.Equal(result.valuePT1, 23)
|
||||
|
||||
// t.Log(result.valuePT2)
|
||||
is.Equal(result.valuePT2, 4)
|
||||
}
|
||||
|
||||
func TestExample4(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(example4))
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
// t.Log(result.valuePT1)
|
||||
is.Equal(result.valuePT1, 70)
|
||||
|
||||
// t.Log(result.valuePT2)
|
||||
is.Equal(result.valuePT2, 8)
|
||||
}
|
||||
|
||||
func TestExample5(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(example5))
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
// t.Log(result.valuePT1)
|
||||
is.Equal(result.valuePT1, 80)
|
||||
|
||||
// t.Log(result.valuePT2)
|
||||
is.Equal(result.valuePT2, 10)
|
||||
}
|
||||
|
||||
func TestInput(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
// t.Log(result.valuePT1)
|
||||
is.True(result.valuePT1 != 51)
|
||||
is.Equal(result.valuePT1, 6649)
|
||||
|
||||
t.Log(result.valuePT2)
|
||||
is.True(result.valuePT2 != 0)
|
||||
is.Equal(result.valuePT2, 601)
|
||||
}
|
||||
|
||||
// first: 51 false
|
||||
10
day11/example.txt
Normal file
10
day11/example.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
...#......
|
||||
.......#..
|
||||
#.........
|
||||
..........
|
||||
......#...
|
||||
.#........
|
||||
.........#
|
||||
..........
|
||||
.......#..
|
||||
#...#.....
|
||||
140
day11/input.txt
Normal file
140
day11/input.txt
Normal file
@@ -0,0 +1,140 @@
|
||||
..............................#.........................#.......................#..............................#.........................#..
|
||||
....#.....#...................................#.............................................................................................
|
||||
.....................................#..................................#...................................................................
|
||||
...................................................#....................................................................#...................
|
||||
...............................................................#..................#...............................#.........................
|
||||
...............#.......................................#...................................#.....#.......#.........................#........
|
||||
............................................................................................................................................
|
||||
............................................................................#...............................................................
|
||||
.......#.......................#....................#.......................................................................................
|
||||
........................#..................#....................................................................#...........................
|
||||
..#.......................................................#.........#....................#....................................#.............
|
||||
..............#...........................................................#..........................................................#......
|
||||
......................................#...........................................#..........................#..............................
|
||||
.....................................................#.........#..........................................................................#.
|
||||
#.......#....................................#.................................................#............................................
|
||||
..............................#.......................................#..............#....................#..........#......................
|
||||
....#...................................#...................................................................................................
|
||||
....................................................................................................#.......................................
|
||||
.....................#...........#...............................................#..................................................#.......
|
||||
...............................................#.........#..................................................#..................#............
|
||||
..........................................................................#...............#........................#........................
|
||||
.................#.......................................................................................................#..................
|
||||
......................................................................................#..................#..............................#...
|
||||
.............#...................................................................................#..........................................
|
||||
#...........................#..........#....................................................................................................
|
||||
.........#........................................................................#...............................#.........................
|
||||
.....................#.........................#.....................................................#....................#......#..........
|
||||
.....................................................................#......................................................................
|
||||
................................#.....................................................................................................#.....
|
||||
...............#..........................................#.................#................#..............................................
|
||||
....................................#...........................#...........................................#...............................
|
||||
.......#...................#................#.......................................#..............................#......................#.
|
||||
......................#.................................................#................................................#..................
|
||||
....................................................#......................................#............#...................................
|
||||
.............#........................#..........................................................#.............#............................
|
||||
...................#..............................................................#.........................................................
|
||||
.........................................................#..................#..........#....................................................
|
||||
........................#.....................#..............................................#.........................................#....
|
||||
.................................................................#.........................................#...................#............
|
||||
...................................................#........#.....................................#......................#..................
|
||||
.........#....................#.......#................................................................#............#.......................
|
||||
#.............................................................................#.....................................................#.......
|
||||
..................#.......#.................................................................................................................
|
||||
.............#........................................................#........................#................#..........#..............#.
|
||||
.....................................................#......................................................................................
|
||||
.......#...............#.................#......................#................#..........................................................
|
||||
...................................#.....................................................#............................#.....................
|
||||
............................................................................................................................................
|
||||
...............................#........................................#.........................#.........................................
|
||||
.....#.........#...............................#...................#.....................................................................#..
|
||||
............................................................................................................................................
|
||||
..........#......................................................................#..........................................................
|
||||
.........................................#.............................................#......#...................#...................#.....
|
||||
........................#.....#........................................................................#....................................
|
||||
...................................................#.....#...................#..............................................................
|
||||
....................................................................#...............#....................................#........#.........
|
||||
...........................#..............................................................#.................................................
|
||||
...#........................................#.........#.......................................................#..............#..............
|
||||
..........#....................................................#................#...........................................................
|
||||
..................................#..................................................................................#...............#......
|
||||
.................#..........................................................................................................................
|
||||
............................................................................................................................................
|
||||
............................#.............#................................#.........................#.....................#................
|
||||
.........#.........................................#............#.........................#............................................#....
|
||||
....#................................................................#.........................#..............#.............................
|
||||
...................#......................................#.................................................................................
|
||||
..............................#......#..............................................#..............#................#.......................
|
||||
.............................................................................#..............................................................
|
||||
.......#.........................................................................................................................#..........
|
||||
..............#............#....................#...................#............#.......#.................................#................
|
||||
................................#......................#................................................#.................................#.
|
||||
............................................................................................................................................
|
||||
.#......................#......................................#...............................................#............................
|
||||
........................................................................#............................#......................................
|
||||
..................................................#..........................#..........................................#.......#...........
|
||||
.........................................#..........................................#....................#..............................#...
|
||||
......#...............#.................................#...................................................................................
|
||||
....................................#.......................................................................................................
|
||||
...............................................................#................#........#.........................#..........#.............
|
||||
..#........#.....#..........#...................#...................................................#.......................................
|
||||
.......................................#...........................#...........................................#............................
|
||||
.............................................................................#..............................................................
|
||||
.......................#..................................#............#...............#.......#.....................................#......
|
||||
............................................................................................................................................
|
||||
............#.....#................................#...........#...................................................#............#...........
|
||||
...........................................#..............................................#.................................................
|
||||
..................................#..............................................#.....................#....................................
|
||||
..................................................................#.........................................................................
|
||||
...#..........................#............................................#................................................................
|
||||
.......................................................#..........................................#........#........#.......................
|
||||
.......................................#.................................................................................#......#...........
|
||||
.................................................#..........#.........#.......................#.............................................
|
||||
............................................................................................................................................
|
||||
....#...........#........................................................................................#.......#...........#..............
|
||||
......................#...........#.......#....................#..............#.....#.......................................................
|
||||
.........#...............................................................................#..................................................
|
||||
..................................................#.........................................................................................
|
||||
...................#......................................#...........................................#...........................#......#..
|
||||
.............#..........#.....................#....................#........................................................................
|
||||
...............................................................................#.....#.....#.................#......#.......................
|
||||
...#.........................#...................................................................#........................#.................
|
||||
............................................................................................................................................
|
||||
.......#.........#..........................................#...............................................................................
|
||||
.................................#..............................................................................................#...........
|
||||
........................................................................#..............#.......#..................#........................#
|
||||
.#...................................#......#......#........................................................................................
|
||||
............................................................................................................................................
|
||||
.............#................#............................................................#..............#.................................
|
||||
......#.....................................................#.......................#................#...............................#......
|
||||
...................#..............................................#.......................................................#.................
|
||||
....................................#.....................................#.................................................................
|
||||
........................................................................................................#.......#...........................
|
||||
....#.....................................#...............#...................#...............#.........................................#...
|
||||
.....................................................................................#......................................................
|
||||
....................................................#...........#......................................................#............#.......
|
||||
........................#...................................................................................#...............................
|
||||
............................................................................#.....#.........#......................#........................
|
||||
...#.....#.....#.......................#....................................................................................................
|
||||
............................................................................................................................................
|
||||
......................................................................#.....................................................................
|
||||
......................................................................................#............#..........................#.............
|
||||
.....#.............#.........................................................#................#.............................................
|
||||
..............................#..........#............#.....#...........................................................#.............#.....
|
||||
........................................................................#................#..................................................
|
||||
..................................................................................#.........................................................
|
||||
......................#.............#....................#........................................................#.........................
|
||||
.................#................................#.............#.............#.............................................................
|
||||
............................................................................................................................................
|
||||
...#..........................#.............#....................................................#.......#...............#.........#........
|
||||
........#...........#.................#..................................................................................................#..
|
||||
..............#.................................#.....#..........................................................#..........................
|
||||
...........................................................#......#.........................................................................
|
||||
............................#..................................................#.....................................#......................
|
||||
...................................................#.......................................#................................................
|
||||
.#................#................#...............................................#...........................................#.....#......
|
||||
.............#....................................................................................................#.........................
|
||||
.........................#...........................................#.....#......................#..........#..............................
|
||||
........................................#...................#...........................................#...................................
|
||||
...#......#............................................................................#....................................................
|
||||
...............................................#.......................................................................#....................
|
||||
197
day11/main.go
Normal file
197
day11/main.go
Normal file
@@ -0,0 +1,197 @@
|
||||
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) {
|
||||
m := NewMap()
|
||||
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
m.readLine(text)
|
||||
}
|
||||
|
||||
return &result{
|
||||
valuePT1: m.expand(1).sumPaths(),
|
||||
valuePT2: m.expand(999_999).sumPaths(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Map struct {
|
||||
rows int
|
||||
cols int
|
||||
|
||||
emptyRows map[int]bool
|
||||
emptyCols map[int]bool
|
||||
|
||||
*aoc.List[rune]
|
||||
}
|
||||
|
||||
func NewMap() *Map {
|
||||
return &Map{
|
||||
emptyRows: make(map[int]bool),
|
||||
emptyCols: make(map[int]bool),
|
||||
List: aoc.NewList[rune](nil),
|
||||
}
|
||||
}
|
||||
func (m *Map) String() string {
|
||||
buf := &strings.Builder{}
|
||||
fmt.Fprintf(buf, "Map size %d x %d\n", m.rows, m.cols)
|
||||
fmt.Fprintln(buf, "empty rows:", all(m.emptyRows))
|
||||
fmt.Fprintln(buf, "empty cols:", all(m.emptyCols))
|
||||
|
||||
n := m.Head()
|
||||
for n != nil {
|
||||
fmt.Fprintln(buf, toXY(n.Position(), m.cols), n.String())
|
||||
n = n.Next()
|
||||
}
|
||||
|
||||
for row := 0; row < m.rows; row++ {
|
||||
for col := 0; col < m.cols; col++ {
|
||||
if n := m.getRC(row, col); n != nil {
|
||||
buf.WriteRune('#')
|
||||
} else {
|
||||
buf.WriteRune('.')
|
||||
}
|
||||
}
|
||||
buf.WriteRune('\n')
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (m *Map) readLine(text string) {
|
||||
if m.cols == 0 {
|
||||
m.cols = len(text)
|
||||
}
|
||||
|
||||
emptyRow, ok := m.emptyRows[m.rows]
|
||||
if !ok {
|
||||
emptyRow = true
|
||||
}
|
||||
|
||||
row := []rune(text)
|
||||
for col, r := range row {
|
||||
emptyCol, ok := m.emptyCols[col]
|
||||
if !ok {
|
||||
emptyCol = true
|
||||
}
|
||||
|
||||
if r == '#' {
|
||||
m.Add(r, fromXY(col, m.rows, m.cols))
|
||||
emptyCol = false
|
||||
emptyRow = false
|
||||
}
|
||||
|
||||
m.emptyRows[m.rows] = emptyRow
|
||||
m.emptyCols[col] = emptyCol
|
||||
}
|
||||
|
||||
m.rows++
|
||||
}
|
||||
func (m *Map) getRC(row, col int) *aoc.Node[rune] {
|
||||
return m.List.Get(fromXY(col, row, m.cols))
|
||||
}
|
||||
func (m *Map) expand(rate int) *Map {
|
||||
newM := NewMap()
|
||||
|
||||
newM.rows = m.rows + rate*len(all(m.emptyRows))
|
||||
newM.cols = m.cols + rate*len(all(m.emptyCols))
|
||||
|
||||
offsetC := 0
|
||||
for col := 0; col < m.cols; col++ {
|
||||
if empty, ok := m.emptyCols[col]; ok && empty {
|
||||
for r := 0; r <= rate; r++ {
|
||||
newM.emptyCols[offsetC+col+r] = true
|
||||
}
|
||||
offsetC += rate
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
offsetR := 0
|
||||
for row := 0; row < m.rows; row++ {
|
||||
if empty, ok := m.emptyRows[row]; ok && empty {
|
||||
for r := 0; r <= rate; r++ {
|
||||
newM.emptyRows[offsetR+row+r] = true
|
||||
}
|
||||
offsetR += rate
|
||||
continue
|
||||
}
|
||||
|
||||
offsetC := 0
|
||||
for col := 0; col < m.cols; col++ {
|
||||
if empty, ok := m.emptyCols[col]; ok && empty {
|
||||
offsetC += rate
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if n := m.getRC(row, col); n != nil {
|
||||
newM.Add('#', fromXY(offsetC+col, offsetR+row, newM.cols))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newM
|
||||
}
|
||||
func (m *Map) sumPaths() int {
|
||||
var positions []int
|
||||
|
||||
n := m.Head()
|
||||
for n != nil {
|
||||
positions = append(positions, n.Position())
|
||||
n = n.Next()
|
||||
}
|
||||
|
||||
var paths []int
|
||||
|
||||
for i := 0; i < len(positions); i++ {
|
||||
p := positions[i]
|
||||
pXY := toXY(p, m.cols)
|
||||
|
||||
for j := i; j < len(positions); j++ {
|
||||
c := positions[j]
|
||||
if c == p {
|
||||
continue
|
||||
}
|
||||
|
||||
cXY := toXY(c, m.cols)
|
||||
|
||||
path := aoc.ABS(cXY[0]-pXY[0]) + aoc.ABS(cXY[1]-pXY[1])
|
||||
paths = append(paths, path)
|
||||
}
|
||||
}
|
||||
return aoc.Sum(paths...)
|
||||
}
|
||||
|
||||
func all(m map[int]bool) []int {
|
||||
lis := make([]int, 0, len(m))
|
||||
for k, v := range m {
|
||||
if v {
|
||||
lis = append(lis, k)
|
||||
}
|
||||
}
|
||||
sort.Ints(lis)
|
||||
return lis
|
||||
}
|
||||
func fromXY(x, y, w int) int { return y*w + x }
|
||||
func toXY(i, w int) [2]int { return [2]int{i % w, i / w} }
|
||||
41
day11/main_test.go
Normal file
41
day11/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, 374)
|
||||
is.Equal(result.valuePT2, 82000210)
|
||||
}
|
||||
|
||||
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, 9627977)
|
||||
is.Equal(result.valuePT2, 644248339497)
|
||||
}
|
||||
6
day12/example.txt
Normal file
6
day12/example.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
???.### 1,1,3
|
||||
.??..??...?##. 1,1,3
|
||||
?#?#?#?#?#?#?#? 1,3,1,6
|
||||
????.#...#... 4,1,1
|
||||
????.######..#####. 1,6,5
|
||||
?###???????? 3,2,1
|
||||
1000
day12/input.txt
Normal file
1000
day12/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
187
day12/main.go
Normal file
187
day12/main.go
Normal file
@@ -0,0 +1,187 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"slices"
|
||||
"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) {
|
||||
var matches []int
|
||||
var matches2 []int
|
||||
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
status, text, ok := strings.Cut(text, " ")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// part 1 - brute force
|
||||
grouping := aoc.SliceMap(aoc.Atoi, strings.Split(text, ",")...)
|
||||
pattern := []rune(status)
|
||||
// sp := spring{pattern: pattern, grouping: grouping, missingNo: countQuestion(pattern)}
|
||||
// matches = append(matches, sp.findMatches())
|
||||
matches = append(matches, countPossible(pattern, grouping))
|
||||
|
||||
// part 2 - NFA
|
||||
b, a := status, text
|
||||
bn, an := "", ""
|
||||
for i := 0; i < 5; i++ {
|
||||
bn, an = bn+b+"?", an+a+","
|
||||
}
|
||||
b, a = strings.TrimSuffix(bn, "?"), strings.TrimSuffix(an, ",")
|
||||
matches2 = append(matches2, countPossible([]rune(b), aoc.SliceMap(aoc.Atoi, strings.Split(a, ",")...)))
|
||||
}
|
||||
|
||||
return &result{valuePT1: aoc.Sum(matches...), valuePT2: aoc.Sum(matches2...)}, nil
|
||||
}
|
||||
|
||||
type spring struct {
|
||||
pattern []rune
|
||||
grouping []int
|
||||
missingNo int
|
||||
}
|
||||
|
||||
func (s *spring) findMatches() int {
|
||||
matches := 0
|
||||
for _, pattern := range s.genPatterns() {
|
||||
pattern := []rune(pattern)
|
||||
target := make([]rune, len(s.pattern))
|
||||
i := 0
|
||||
for j, r := range s.pattern {
|
||||
if r == '?' {
|
||||
target[j] = pattern[i]
|
||||
i++
|
||||
continue
|
||||
}
|
||||
target[j] = r
|
||||
}
|
||||
|
||||
if slices.Equal(countGroupings(target), s.grouping) {
|
||||
matches++
|
||||
}
|
||||
}
|
||||
|
||||
return matches
|
||||
}
|
||||
func (s *spring) genPatterns() []string {
|
||||
buf := &strings.Builder{}
|
||||
combinations := aoc.Power2(s.missingNo)
|
||||
lis := make([]string, 0, combinations)
|
||||
for i := 0; i < combinations; i++ {
|
||||
for b := 0; b < s.missingNo; b++ {
|
||||
if i>>b&0b1 == 1 {
|
||||
buf.WriteRune('#')
|
||||
} else {
|
||||
buf.WriteRune('.')
|
||||
}
|
||||
}
|
||||
lis = append(lis, buf.String())
|
||||
buf.Reset()
|
||||
}
|
||||
|
||||
return lis
|
||||
}
|
||||
func countPossible(s []rune, c []int) int {
|
||||
pos := 0
|
||||
|
||||
cstates := map[state]int{{}: 1} // current state
|
||||
nstates := map[state]int{} // next state
|
||||
|
||||
for len(cstates) > 0 {
|
||||
for st, num := range cstates {
|
||||
si, ci, cc, expdot := st.springIndex, st.groupIndex, st.continuous, st.expectDot
|
||||
|
||||
// have we reached the end?
|
||||
if si == len(s) {
|
||||
if ci == len(c) {
|
||||
pos += num
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
switch {
|
||||
case (s[si] == '#' || s[si] == '?') && ci < len(c) && !expdot:
|
||||
// we are still looking for broken springs
|
||||
if s[si] == '?' && cc == 0 {
|
||||
// we are not in a run of broken springs, so ? can be working
|
||||
nstates[state{si + 1, ci, cc, expdot}] += num
|
||||
}
|
||||
|
||||
cc++
|
||||
|
||||
if cc == c[ci] {
|
||||
// we've found the full next contiguous section of broken springs
|
||||
ci++
|
||||
cc = 0
|
||||
expdot = true // we only want a working spring next
|
||||
}
|
||||
|
||||
nstates[state{si + 1, ci, cc, expdot}] += num
|
||||
|
||||
case (s[si] == '.' || s[si] == '?') && cc == 0:
|
||||
// we are not in a contiguous run of broken springs
|
||||
expdot = false
|
||||
nstates[state{si + 1, ci, cc, expdot}] += num
|
||||
}
|
||||
}
|
||||
|
||||
// swap and clear previous states
|
||||
cstates, nstates = nstates, cstates
|
||||
clear(nstates)
|
||||
}
|
||||
return pos
|
||||
}
|
||||
|
||||
type state struct {
|
||||
springIndex int
|
||||
groupIndex int
|
||||
continuous int
|
||||
expectDot bool
|
||||
}
|
||||
|
||||
func countQuestion(pattern []rune) int {
|
||||
count := 0
|
||||
for _, r := range pattern {
|
||||
if r == '?' {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
func countGroupings(pattern []rune) []int {
|
||||
var groupings []int
|
||||
inGroup := false
|
||||
for _, r := range pattern {
|
||||
|
||||
if r == '#' {
|
||||
if !inGroup {
|
||||
groupings = append(groupings, 0)
|
||||
}
|
||||
|
||||
inGroup = true
|
||||
groupings[len(groupings)-1]++
|
||||
|
||||
}
|
||||
if inGroup && r != '#' {
|
||||
inGroup = false
|
||||
}
|
||||
}
|
||||
return groupings
|
||||
}
|
||||
70
day12/main_test.go
Normal file
70
day12/main_test.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
_ "embed"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
|
||||
"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, 21)
|
||||
is.Equal(result.valuePT2, 525152)
|
||||
}
|
||||
|
||||
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, 8193)
|
||||
is.Equal(result.valuePT2, 45322533163795)
|
||||
}
|
||||
|
||||
func TestPower2(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
is.Equal(aoc.Power2(1), 2)
|
||||
is.Equal(aoc.Power2(2), 4)
|
||||
is.Equal(aoc.Power2(3), 8)
|
||||
is.Equal(aoc.Power2(4), 16)
|
||||
is.Equal(aoc.Power2(5), 32)
|
||||
is.Equal(aoc.Power2(6), 64)
|
||||
}
|
||||
|
||||
func TestCountGroupings(t *testing.T) {
|
||||
is := is.New(t)
|
||||
is.Equal([]int{1, 3, 1}, countGroupings([]rune(".#.###.#")))
|
||||
is.Equal([]int{1, 3, 1}, countGroupings([]rune(".#.###...#.")))
|
||||
is.Equal([]int{1, 3, 1}, countGroupings([]rune("#.###...#.")))
|
||||
}
|
||||
|
||||
func TestCombination(t *testing.T) {
|
||||
s := spring{
|
||||
pattern: []rune("???"),
|
||||
grouping: []int{1},
|
||||
missingNo: 3,
|
||||
}
|
||||
s.findMatches()
|
||||
}
|
||||
15
day13/example.txt
Normal file
15
day13/example.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
#.##..##.
|
||||
..#.##.#.
|
||||
##......#
|
||||
##......#
|
||||
..#.##.#.
|
||||
..##..##.
|
||||
#.#.##.#.
|
||||
|
||||
#...##..#
|
||||
#....#..#
|
||||
..##..###
|
||||
#####.##.
|
||||
#####.##.
|
||||
..##..###
|
||||
#....#..#
|
||||
7
day13/example00.txt
Normal file
7
day13/example00.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
#.##..##.
|
||||
..#.##.#.
|
||||
##......#
|
||||
##......#
|
||||
..#.##.#.
|
||||
..##..##.
|
||||
#.#.##.#.
|
||||
1301
day13/input.txt
Normal file
1301
day13/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
11
day13/input07.txt
Normal file
11
day13/input07.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
##.#.##.#
|
||||
...#..#..
|
||||
.##...#..
|
||||
.##...#..
|
||||
.#.#..#..
|
||||
##.#.##.#
|
||||
.#...####
|
||||
..#.#..##
|
||||
...#...##
|
||||
.#....#.#
|
||||
.#....#.#
|
||||
179
day13/main.go
Normal file
179
day13/main.go
Normal file
@@ -0,0 +1,179 @@
|
||||
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) {
|
||||
maps := []Map{}
|
||||
m := Map{}
|
||||
r := &result{}
|
||||
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
|
||||
if text == "" {
|
||||
maps = append(maps, m)
|
||||
m = Map{}
|
||||
} else {
|
||||
m = append(m, []rune(text))
|
||||
}
|
||||
}
|
||||
maps = append(maps, m)
|
||||
|
||||
for _, m := range maps {
|
||||
sum, sum2 := findSmudge(m)
|
||||
|
||||
if sum == -1 || sum2 == -1 {
|
||||
mr := Map(aoc.Transpose(m))
|
||||
Hsum, Hsum2 := findSmudge(mr)
|
||||
|
||||
if sum2 == -1 {
|
||||
sum2 = Hsum2 * 100
|
||||
}
|
||||
|
||||
if sum == -1 {
|
||||
sum = Hsum * 100
|
||||
}
|
||||
}
|
||||
|
||||
r.valuePT1 += sum
|
||||
r.valuePT2 += sum2
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
type Map [][]rune
|
||||
|
||||
func (m Map) String() string {
|
||||
var buf strings.Builder
|
||||
for i, row := range m {
|
||||
if i == 0 {
|
||||
fmt.Fprint(&buf, " ")
|
||||
for j := range row {
|
||||
fmt.Fprintf(&buf, "%d", j)
|
||||
}
|
||||
fmt.Fprint(&buf, "\n")
|
||||
}
|
||||
|
||||
fmt.Fprintf(&buf, "%d ", i)
|
||||
buf.WriteRune(' ')
|
||||
buf.WriteString(string(row))
|
||||
buf.WriteRune('\n')
|
||||
}
|
||||
buf.WriteRune('\n')
|
||||
return buf.String()
|
||||
|
||||
}
|
||||
|
||||
// func findReflection(m Map) (int, bool) {
|
||||
// candidates := make(map[int]bool)
|
||||
// var candidateList []int
|
||||
|
||||
// for _, row := range m {
|
||||
// for col := 1; col < len(row); col++ {
|
||||
// if v, ok := candidates[col]; !ok || v {
|
||||
// candidates[col], _ = reflects(row[:col], row[col:])
|
||||
// }
|
||||
// }
|
||||
// candidateList = all(candidates)
|
||||
// if len(candidateList) == 0 {
|
||||
// return 0, false
|
||||
// }
|
||||
// }
|
||||
|
||||
// if len(candidateList) == 1 {
|
||||
// return candidateList[0], true
|
||||
// }
|
||||
|
||||
// return 0, false
|
||||
// }
|
||||
|
||||
type level struct {
|
||||
blips int
|
||||
nequal int
|
||||
fail bool
|
||||
}
|
||||
|
||||
func findSmudge(m Map) (int, int) {
|
||||
candidates := make(map[int]level)
|
||||
|
||||
for _, row := range m {
|
||||
for col := 1; col < len(row); col++ {
|
||||
candidate := candidates[col]
|
||||
if candidate.fail {
|
||||
continue
|
||||
}
|
||||
|
||||
eq, bl := reflects(row[:col], row[col:])
|
||||
if !eq {
|
||||
candidate.nequal++
|
||||
}
|
||||
candidate.blips += bl
|
||||
|
||||
if candidate.nequal > 1 || candidate.blips > 1 {
|
||||
candidate.fail = true
|
||||
}
|
||||
|
||||
candidates[col] = candidate
|
||||
}
|
||||
}
|
||||
|
||||
a, b := -1, -1
|
||||
for i, cand := range candidates {
|
||||
if !cand.fail && cand.blips == 1 {
|
||||
b = i
|
||||
}
|
||||
if !cand.fail && cand.blips == 0 {
|
||||
a = i
|
||||
}
|
||||
}
|
||||
|
||||
return a, b
|
||||
}
|
||||
|
||||
func reflects(a, b []rune) (bool, int) {
|
||||
c := min(len(a), len(b))
|
||||
|
||||
a = append([]rune{}, a...)
|
||||
b = append([]rune{}, b...)
|
||||
aoc.Reverse(a)
|
||||
a = a[:c]
|
||||
b = b[:c]
|
||||
|
||||
blips := 0
|
||||
for i := range a {
|
||||
if a[i] != b[i] {
|
||||
blips++
|
||||
}
|
||||
}
|
||||
|
||||
return blips == 0, blips
|
||||
}
|
||||
|
||||
func all[T comparable](m map[T]bool) []T {
|
||||
lis := make([]T, 0, len(m))
|
||||
for k, v := range m {
|
||||
if v {
|
||||
lis = append(lis, k)
|
||||
}
|
||||
}
|
||||
return lis
|
||||
}
|
||||
42
day13/main_test.go
Normal file
42
day13/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, 405)
|
||||
is.Equal(result.valuePT2, 400)
|
||||
}
|
||||
|
||||
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 > 1704) // attempt 1
|
||||
is.Equal(result.valuePT1, 30705)
|
||||
is.Equal(result.valuePT2, 44615)
|
||||
}
|
||||
10
day14/example.txt
Normal file
10
day14/example.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
O....#....
|
||||
O.OO#....#
|
||||
.....##...
|
||||
OO.#O....O
|
||||
.O.....O#.
|
||||
O.#..O.#.#
|
||||
..O..#O..O
|
||||
.......O..
|
||||
#....###..
|
||||
#OO..#....
|
||||
100
day14/input.txt
Normal file
100
day14/input.txt
Normal file
@@ -0,0 +1,100 @@
|
||||
...#.O.#.#.O.O....#...O....#..#........OO.O#...O..O#O#.......O.O....O.....#...OO#.O....OOO..OO#..#..
|
||||
.##.....#.OOO.OO#...O.......O#..O.##OO.O.......O##....O....#O..O..#.#....#OO..#...O.O#.#...#....#O.O
|
||||
O...##.O.O.O.O..#.#.....#O....#..#O..O...O..OO..O...##.......OO#..OOO..#O..#.O#.O......#..#O..O..O.O
|
||||
..OO....OOO....O.O..OOO.....O........#...O.O.O.O..O#.O...O..#.#O........O.....#O...##....#...#.#....
|
||||
##.O.O#..O..##O.....O.#.....O.O#O.O..#...#...OO.##OOO...OO#...O...O........O.#.O.........#O.#...#.#.
|
||||
.#.O.O.....#..O###..O#.#..O....O.O....#...##.O..O.OOO..O.O..O#.O..O....#.#.O..#..##O...O....#O#.....
|
||||
.......O...##..O..O##..##...O....###.O.#.#.O......O...O.O......#O.....#..O..O#..##O.O#O##O....O#....
|
||||
.#O..#....##.##..O#..#..#..O........OO....#..##.O.#.O.O..OO.O.O#..#O##O......OO...O...OO...#....OO..
|
||||
#.....O#......O#.....#..O...#O..OO..OO.#O...O...O.........O...#O...O.....#.....#...#.....O##.O.....O
|
||||
OO.O..O...O......#.O......#O....#..#.#...O.O....O.#.O#...O........O......#.#O#.O...O.........#O....O
|
||||
O.O..O..#......O.O.OO...OO..##.....OO.....#.O...O.#.#...OO..OO.O.........#O..#.O...O#.#..O..OO.##O..
|
||||
..#.......O....#...#....##..O.O......O....O#.O..O..#.#.O#O.O.#...#.##.....O...O.O...O.#...O...O.#...
|
||||
.O...#..O.....O.O.....OO.O.O.......O..O..........#...O..O..O......O....#OOO...O#O...#.O#........O...
|
||||
.OO#....#.....O...#.###..#..O..O.....#O..#..OO...OOO#.O#..O#O........#..#.O..OOO#O#..O..OO........#.
|
||||
..O.....#..#..O.............#..O.O..O#.......#.O.........O.#..OO.O..#..##..O.O#O....OO.O.O.O.....O#.
|
||||
........#O..O#OO...#.##O.O....O...O..........##.#O..O......O..O.#...#O.O.OO...#.#OOO.#...O#....#.O.#
|
||||
.....O.O...#OO#.OO#......#..O.O..#.OO.......#...#.O.O#.O.#O.O#..#O##..OO...#......#.O....#.....O.#O.
|
||||
.O#OOOO...#.#..........O#.#.#.#.O....O..O...O...OOO.O.O.O..OO..O..O#.#...#....#...#O#.OO.O..#.O#....
|
||||
OO#OO..#.O.#....#..#.#..#O#.O#O#.#..O.O....#..O...OO..O..#........#.O...O#.#.....#....O.....#.O.....
|
||||
.O.....#...OO...#..O..#..O..O##..OO...O....#.O.#............###.O.#..O..O.........O..#.O..O.#OO.#...
|
||||
.##O.#.O.#....O..O..#..O.#.O..##O..O......OO...#...O..OO#....O..O#O.##.OO#...O#...#.......O.O#.#OO..
|
||||
.OO#O#...O..##.O......O..O.O....O...OOO.O..#...O#.#.O.OOO..#...#.##..OO..................OOOOO...###
|
||||
.#..##...####.O#...O........O...#O..O..O....O##O..O..OO..#.....#...O.....OO......OOO.#..O.##OO##...#
|
||||
....O#........O##.O...O#..#.O#O...O...O.O........#..#.#.O......O..#.....#.O..#.#..#..#O....O##...#..
|
||||
.O..OO.O##..O...O.OO....O.OOO..#O#.O##......O.O#....O#O.O......#.O..#O..#O.........#..OO....#.OO..O.
|
||||
.#OO..#OO.###........#...#..#.O..#O.O#O...O.#.....O...#......O.......#.O.#.##.O..#O.O###OOOO...#..O.
|
||||
##...OOO.#..........O#...O#.....OO...O#..OO.OO.#.OOO..OO....O..OOO...##O...O.........##O...#.#O.....
|
||||
.#....O.....#OO.O.OO..O......#.OO..#O...O..##O.#O....#O.OO..#O.OO...O..O.#..##...O......#O##OO.#.O..
|
||||
.#..O....O....#......#.O.##...OO.O.O...O.OO.O....#...#..O....O#O..#...#.#..#...OO......OOO...O..#...
|
||||
#.#OO.#....O.#.OO....#........O.O.##...O.#.................OOOO....O..#......O..#.#...O....#.O#OO.#O
|
||||
....O.O.......##..O.........OO#O..O.O#.#.#.O....#..OO.O..O#O....O..O.O......O.O.#..O.......O.O..O.O#
|
||||
...........#OO...O....#.O.#..#O.O#.....O..O.....O#.....OO.#O...#O.#O.#.....OO.O.O....OO......O#O.O..
|
||||
OOOO.OO..O....O.O...O..#.........O#.##OOO#.O..O.O.O......O..#..O..#..#.O..O....O#O.#OO..O.O...O#.##.
|
||||
##.O.#O.#OO#..........OO#.OO.#..#.#......#.OO...#.O.O.......O##....O..O..#.#.#O....O..##.#OO.O..O..O
|
||||
#O...OO..#.#....##.O#.#...##OO#........O#.O..O#.........O.O.#....O.#.O.......O..OOO......O#O.###.O..
|
||||
....O#....#..O...#.#.....O.O#O..#O....O...O.OO#...O..O#.##.O.....O...#..#.O.....O...O#..O.#...#.#O..
|
||||
O.OO......#..O...O.O....#...OO..O#.O..OO..#.##.....#....O.O#O#.O....O..#..OOO..O....O.O..#..O.O..O..
|
||||
.#..#..##O..O.....O#.#.O.O..O..OO..O.O..OO.##.O...O..O#........O.............#.OO..#......O..#O#OOO.
|
||||
.#..##...O.#..OO...O..#..#O#..#..##.O#.#.....#....O.O..O.........#.###...#.O##..O...#.O.OO..........
|
||||
........#O.......O...O#.#....#.O#....#..O.....OO........O...#.........##.....O...O#.O...O.O..#OO.O.#
|
||||
.#..#.O##..##.O#.#.......OO...OO#...#O#............#.#...#...O...#.O..#O.#.O.........O..OO.O...O.#..
|
||||
#.O#OO...OO.O.#...##........#....O.#.O.....##.#.O.O.O.#..O#...O..#......#..O...###O..OO..##..OO.#OOO
|
||||
.OO...#O....O##.O...O.#....O...#O.......O.....OO.O...O..#...OO.OO.O#...O##.....O..#.#...#OO......O..
|
||||
..O..#...O...##..O...O..OO.O.O.O.....#.....O.....O..#OOO.....OOOO#.#.O..O..#........O.#O#.#O..O.##..
|
||||
.....##.....O.....O#...##.OOO....O.O..O.#.#O........OO.....#...##...#.#......#....OO.O.....#O....#.#
|
||||
..O.OO#....O..O.#O.#OO#..#.O.##.#..#.OO##....O#...#..O.#..#...#.#....OOOO.#...OOOO..O.........##O.O.
|
||||
O.O.#......O#...O..#.......#O.O..OOOO..#....#.#.OO.O..#O......#.#....#...#..O....#O.OO..O.......#.#.
|
||||
...O.O....O#......#.O.O....O#.#..#O.#.....#...#...#.O#.........O.OO..O###...O....O.#.O.#.....##..O..
|
||||
.#.OO...O#O.....O#....O......OO...OO.OOOOOO##....#..#..#O.#.OO....O#..OO.#O........O#..O.O#.#.......
|
||||
#OO#.#.....O#OOO#...O.........#......O#.......O.....O#.#O...O........#....O...O.....#.......##.OOO#.
|
||||
..#.O##..#OO..#....#O....#....#..........#O...#...O.#.O.O###O..O..#...#.OO....##..O.O.O.....O..O....
|
||||
....OOO#.#......#..O.O......##O.#.O.#.O.OO....#..O.......#.....#O.O...##O###.##.##..#.O.#.O#..#..O#.
|
||||
......O#OO......#.#..#.O#OO#O..O#O.O##.......O...O........O......O#.....#..#....#...#.#..O...O##.#O.
|
||||
#..OO..O.O.....#O.O.#.#......O......O.#....O.#OO.........#.O.O#..#..#.O..O.#..#...#...O.#..........O
|
||||
..O#OOO#.#.....O.....O..##.#..OOO.O..#..O#...##O..OO...#....#..#...#...OO.....##OO#.OO...#.O....#.#.
|
||||
#.#O.............#....O#.....O.....O.##O.....#.#.#.....O....O...O...##..O...#........#O..##.#.....##
|
||||
.O.....O...#O.#.O#..O#........#.##...O##O..........O##.O......O..#....##....###......O##..##O..#.O#.
|
||||
.#...#..#..O.O.............#....O.OO.....OO#O.....OO..OOO#O.O.O.O...#...#.........OO..O#.O...#.##..#
|
||||
..O...#O#.......#OO..........OO#..#.....OO#...#OO.O#....OO....O..O..#....#OO......O#O...#......O..O.
|
||||
O.......O..O..#O.....O#O.........O##.O#.#.O.O....##....O.#....O....OOO..#O#...#...O.O#.O.....O.O#.O.
|
||||
O.#O....O..##....O.........##.OO###....O...O...O..O#O#...#O.O.O....#..O..#..#.O.......###..#....#..O
|
||||
.........O..#O...O..OO.....#...O..#O#.....O....#O#....##...#.OOOO.O..O#...O..O.O#.#..O.O..#..#.OO...
|
||||
...#.....#..OO.O.#.#.O.....O#...#..O...O..O..#...O..O.O..#...#.###..#..##O.#.#O.......O..##O.O.O#...
|
||||
.##O......O....#....O....#O..#.....#.O..O.O.O..#.#O.....O#.O...#.#O.#...#.........O....O....OO..O...
|
||||
.OO.O.O.O#O..O##.O...OO.....O..O....O....#..#...O.O...O....O.#.O......#O.#.O#O..O...O.O.#.O..O.#....
|
||||
O#..#.#..#..#...#.O...O.###.##.OO.O.#.OOO..O..#O.#.O...OO...O.OOO....#.....#OO.O##.O.#.#O...#.#.....
|
||||
.#.....#.........O.#.........#...OO..O.#.O...O##O...#..O.O.OO#....###.OO.....#..........#.#OO...O.O.
|
||||
........OO..O.O.#..O.#.......#.#O.OOO...OO.O............O#O#...O...#.O.....#...........O...#..OO.O#O
|
||||
..#.#.#...O....#O.......#...#...O###.O.....O.O.OO....#O...OO.O.O........O.O.#O.O....OO.....OO.....#.
|
||||
#..OOO#......O.#.O#...#..#..O..O.O.O.#...O#OOO.#...O.#.OO.#O..#....#..#O....O.#.O...O...O#OO...#....
|
||||
.....#.....##...O....#..O..O.....O#OO.#O#.....O...O.##.#........O..O........#.#......##......#..#..O
|
||||
O..O....O.##..#.#O##.#.....OO....O.##O......#...#..OO.O.....#...#........O..O#O##.O.......#..##O..##
|
||||
#.....#O....O...#OOO#..O#.O.....O..OO.#..#.#.O#..O..O#.O###....O......O.#.O..#O.....#.......##O.O..O
|
||||
O.O.#..#....O....O.......#.O..O#O#.O..........#O.....#OO.O...#.OO.....#...O....OO....#...O....O.#..O
|
||||
..#...OO....OO......O....#..#..........##..##..#.....##...#..#O.....#OO......#........O.....O..O...#
|
||||
.OO#...O#.O....#.........OO#...O#..O.#..O.O.O.#O......##.O.......O...O...###.O......O....O...#.OO#..
|
||||
..O..O#O.#..O.#O...OOO#O.#.O....O.#......O....#....###....OO......O...#...OO.#....O........O#..#..OO
|
||||
#..OO..O......#...##..O#.O........O.O...##.#O...O...#O#.O.O....#.............#.O#.#..O..#..OO#.....#
|
||||
#..........O...O##.O#..O..OO..O.....#O.#.O......#......O.O....##.O#OO..O.O..O.O.O..#..O....O..#....O
|
||||
.O.O...O.#..O.O....#.#.O.O.##.##..O..#OOOO.###...#O...#...O.....O...#.##.OO..O.#..#.O.#.......O....#
|
||||
#....#....OOOOOOO.#...OO....##O.#..#......O..#..........O......##..O..###..#.O....O.......OO......#.
|
||||
.O.O..##.O.#O.#...#....O..O.....#..##......O.......O..O#.O##.#........O..#.O.#.O.O..##..###..##.#...
|
||||
..OOO..O##..OOOO.O.....OO##..O..O.#....#.....OO......O.OOO#...#O.OO...O.O......O#..O.##....###...#.O
|
||||
....O...O.O....#..O#.O.....O.O.#.......O##...O#..OO.O.O##...#.....O#.###....O....#O.........OO..O.O.
|
||||
O#.O......##..#.#..............#......#.#.OO#......##O#OO..OOO..##.O##....#..O...#......##O.O##...OO
|
||||
...#OO....OO...O#.#..##....OO.#..#O......O#....#.O.....O.#O..OO.#..OO...O#.O#....O.#.OO.O.O#..O.....
|
||||
#..O.OO#O...O..O..........#..#.#..#..#O.....#O#..O....#..O...O.#.#O#.#OO.....OOO.#..#.........O...O#
|
||||
....O......#..........O...#.....OOOO........#.#OO.O............O...#....O........#....#....#........
|
||||
...O.......###...O.O...#O.##O.OOO.........O.###.O.......O....O.O...O.#.....#..#O..#..OO..O.O...O....
|
||||
O.O#....##.O.O.....O....#............OO.#O...O..#...##.#.#O#O.#.....O......O....#.OO#.O#....#.....O.
|
||||
..O####.O.........O...........OO..OO.#.....O.......#..O#.O....O#...##.......#.#....O..O..O#..##.....
|
||||
.#..#......O.##.O.OOO.O.OO....O.......#......#.O...OOOO...O..#..#.O.#......O...O#.#.O.#.O....O....O.
|
||||
##....O.O..O..O.#...O##.......O....#...#OOO.O..##.....#....O.......#O..#.#O..O.#.......O..#.O.O#.O##
|
||||
...O....O#O.#...#......#..O.O.O.O...O.....O..O.#..#.....O#...OO...#.O.O....#..OOO...#.....OO.OO..O..
|
||||
O##.O.##.O#OO...OO...OO..O....OO#O.#O..O.O....OO..........O..#.O.#O#.......O.O..#O#....#..#...#O..#.
|
||||
.#.#..........#.......#..OO#....O.#.#.O.....OO.#.O..#.#.O....#..O....#..#..O.#O#O.....#.O.O.#O.O.#O.
|
||||
.O.#....##O...#..OOO.#......#...#.O.......OO....#.......#..#.OOO........OO..O..###O##..O.....O##....
|
||||
OO##..O#....O.##.......O...#........O.O...#O#.#.OOO....#......#.#O.O.O..O..O...#.#.O.O.OOO.O#O......
|
||||
#O...#....OOO.O...#O....O...O..........O..#..O#.O..#O.....#......#.#..#.OO..#....#O#....O...O....##.
|
||||
.OOOO......##.#O.#O...#......O..#..O..#.O...O.OO...............#O...O..##..#.#....O...O..O.##..O.O..
|
||||
157
day14/main.go
Normal file
157
day14/main.go
Normal file
@@ -0,0 +1,157 @@
|
||||
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) {
|
||||
var maplist []Map
|
||||
var m Map
|
||||
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
if len(text) == 0 {
|
||||
maplist = append(maplist, m)
|
||||
m = Map{}
|
||||
}
|
||||
|
||||
m = append(m, []rune(text))
|
||||
}
|
||||
maplist = append(maplist, m)
|
||||
|
||||
score1 := 0
|
||||
for _, m := range maplist {
|
||||
m = aoc.Transpose(reverse(m))
|
||||
m.Sort()
|
||||
score1 += m.Score()
|
||||
}
|
||||
|
||||
score2 := 0
|
||||
type record [5]int
|
||||
var current record
|
||||
memo := make(map[record]int)
|
||||
|
||||
for _, m := range maplist {
|
||||
// fmt.Println(m)
|
||||
|
||||
m = aoc.Transpose(reverse(m))
|
||||
|
||||
for i := 0; i < 1_000_000_000; i++ {
|
||||
m, current = cycle(m)
|
||||
|
||||
v, ok := memo[current]
|
||||
if ok && v > 1 {
|
||||
counts := aoc.Reduce(
|
||||
func(i int, v int, counts [3]int) [3]int {
|
||||
counts[v]++
|
||||
return counts
|
||||
}, [3]int{}, maps.Values(memo)...)
|
||||
|
||||
// fmt.Println(i, counts)
|
||||
i = 1_000_000_000 - (1_000_000_000-counts[0]-counts[1])%counts[2]
|
||||
clear(memo)
|
||||
}
|
||||
memo[current] += 1
|
||||
// fmt.Println(i, current, v)
|
||||
}
|
||||
score2 += m.Score()
|
||||
}
|
||||
|
||||
return &result{valuePT1: score1, valuePT2: score2}, nil
|
||||
}
|
||||
|
||||
type Map [][]rune
|
||||
|
||||
func (m Map) String() string {
|
||||
var buf strings.Builder
|
||||
for _, row := range m {
|
||||
buf.WriteString(string(row))
|
||||
buf.WriteRune('\n')
|
||||
}
|
||||
buf.WriteRune('\n')
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
func (m *Map) Sort() {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
for _, row := range *m {
|
||||
base := 0
|
||||
for i, r := range row {
|
||||
if r == '#' {
|
||||
base = i + 1
|
||||
continue
|
||||
}
|
||||
if r == 'O' {
|
||||
if base < i {
|
||||
row[base], row[i] = row[i], row[base]
|
||||
}
|
||||
base++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func (m *Map) Score() int {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
sum := 0
|
||||
max := len(*m)
|
||||
for _, row := range *m {
|
||||
for i, r := range row {
|
||||
if r == 'O' {
|
||||
sum += max - i
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func reverse(m Map) Map {
|
||||
for _, row := range m {
|
||||
aoc.Reverse(row)
|
||||
}
|
||||
return m
|
||||
}
|
||||
func cycle(m Map) (Map, [5]int) {
|
||||
var current [5]int
|
||||
|
||||
m.Sort()
|
||||
current[0] = m.Score()
|
||||
|
||||
m = aoc.Transpose(reverse(m))
|
||||
m.Sort()
|
||||
current[1] = m.Score()
|
||||
|
||||
m = aoc.Transpose(reverse(m))
|
||||
m.Sort()
|
||||
current[2] = m.Score()
|
||||
|
||||
m = aoc.Transpose(reverse(m))
|
||||
m.Sort()
|
||||
current[3] = m.Score()
|
||||
|
||||
m = aoc.Transpose(reverse(m))
|
||||
current[4] = m.Score()
|
||||
|
||||
return m, current
|
||||
}
|
||||
45
day14/main_test.go
Normal file
45
day14/main_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
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, 136)
|
||||
is.Equal(result.valuePT2, 64)
|
||||
}
|
||||
|
||||
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.valuePT2 < 87286) // first submission
|
||||
is.True(result.valuePT2 < 87292) // second submission
|
||||
is.True(result.valuePT2 < 87287) // third submission
|
||||
|
||||
is.Equal(result.valuePT1, 110407)
|
||||
is.Equal(result.valuePT2, 87273)
|
||||
}
|
||||
1
day15/example.txt
Normal file
1
day15/example.txt
Normal file
@@ -0,0 +1 @@
|
||||
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7
|
||||
1
day15/input.txt
Normal file
1
day15/input.txt
Normal file
File diff suppressed because one or more lines are too long
136
day15/main.go
Normal file
136
day15/main.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"slices"
|
||||
"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) {
|
||||
r := &result{}
|
||||
|
||||
var ops []string
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
ops = strings.Split(text, ",")
|
||||
|
||||
r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int {
|
||||
sum += hash(t)
|
||||
return sum
|
||||
}, 0, ops...)
|
||||
}
|
||||
|
||||
var boxen boxes
|
||||
|
||||
boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
|
||||
return b.Op(op)
|
||||
}, boxen, ops...)
|
||||
|
||||
r.valuePT2 = boxen.Sum()
|
||||
|
||||
log(boxen)
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func hash(s string) int {
|
||||
var sum int
|
||||
for _, a := range s {
|
||||
sum += int(a)
|
||||
sum *= 17
|
||||
sum %= 256
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
type lens struct {
|
||||
label string
|
||||
value int
|
||||
}
|
||||
|
||||
func (l lens) String() string {
|
||||
return fmt.Sprintf("[%s %d]", l.label, l.value)
|
||||
}
|
||||
|
||||
type box []lens
|
||||
|
||||
func (lis box) String() string {
|
||||
var buf strings.Builder
|
||||
if len(lis) > 0 {
|
||||
buf.WriteString(lis[0].String())
|
||||
}
|
||||
for _, l := range lis[1:] {
|
||||
buf.WriteString(l.String())
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type boxes [256]box
|
||||
|
||||
func (lis boxes) String() string {
|
||||
var buf strings.Builder
|
||||
buf.WriteString("Boxes:\n")
|
||||
for i, b := range lis {
|
||||
if len(b) > 0 {
|
||||
fmt.Fprintf(&buf, "Box %d: %v\n", i, b)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (lis boxes) Op(op string) boxes {
|
||||
if a, _, ok := strings.Cut(op, "-"); ok {
|
||||
i := hash(a)
|
||||
|
||||
pos := slices.IndexFunc(lis[i], func(l lens) bool { return l.label == a })
|
||||
|
||||
if pos >= 0 {
|
||||
lis[i] = append(lis[i][:pos], lis[i][pos+1:]...)
|
||||
}
|
||||
} else if a, b, ok := strings.Cut(op, "="); ok {
|
||||
i := hash(a)
|
||||
v := aoc.Atoi(b)
|
||||
|
||||
pos := slices.IndexFunc(lis[i], func(l lens) bool { return l.label == a })
|
||||
|
||||
if pos == -1 {
|
||||
lis[i] = append(lis[i], lens{a, v})
|
||||
} else {
|
||||
lis[i][pos].value = v
|
||||
}
|
||||
}
|
||||
|
||||
return lis
|
||||
}
|
||||
func (lis boxes) Sum() int {
|
||||
// return aoc.Reduce(func(b int, box box, sum int) int {
|
||||
// return aoc.Reduce(
|
||||
// func(s int, lens lens, sum int) int {
|
||||
// return sum + (b+1)*(s+1)*lens.value
|
||||
// }, sum, box...)
|
||||
// }, 0, lis[:]...)
|
||||
|
||||
var sum int
|
||||
for b := range lis {
|
||||
for s := range lis[b] {
|
||||
sum += (b + 1) * (s + 1) * lis[b][s].value
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
41
day15/main_test.go
Normal file
41
day15/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, 1320)
|
||||
is.Equal(result.valuePT2, 145)
|
||||
}
|
||||
|
||||
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, 503154)
|
||||
is.Equal(result.valuePT2, 251353)
|
||||
}
|
||||
10
day16/example.txt
Normal file
10
day16/example.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
.|...\....
|
||||
|.-.\.....
|
||||
.....|-...
|
||||
........|.
|
||||
..........
|
||||
.........\
|
||||
..../.\\..
|
||||
.-.-/..|..
|
||||
.|....-|.\
|
||||
..//.|....
|
||||
110
day16/input.txt
Normal file
110
day16/input.txt
Normal file
@@ -0,0 +1,110 @@
|
||||
\.......................\..........................................-..................-.../................-..
|
||||
....../.......\...-......-.|...\..............\.................|............././....-........................
|
||||
...............-...-........................................\......\..-.............|......-....\....-........
|
||||
..\..|.|...........................-.|........................................./.|....|................|......
|
||||
|../................|............................................................\........../..\..............
|
||||
........\............../................/..........................\...\....|............./....-.........\\...
|
||||
.................-...-...................\../........-|.................../......-...........|................
|
||||
........-............/...|-............-.....\.|..............-....-../\../..................\...\././........
|
||||
........................-|................................................................-........-..........
|
||||
-......./.................|.....\.................\.....//............-........./..../....|...................
|
||||
....-.............-........-..........-|.......|...../...\...................\.....................|..........
|
||||
...|...\.........|.................|.....|....-....\.......\./........................-.../..../.....-........
|
||||
....|....-.-..............\.........|.......................-.......-..............\................/.........
|
||||
.....|.\...........-.................-.-........../...\............|...............|...|......./.......|...../
|
||||
.....\.........................-.../..-./...\...................../......\...-.......|.\........-|............
|
||||
............|.....................................-....../....\.............../-...|...\..\................./.
|
||||
......-./|....../............|.........\............-../...-......./.\..\....../......|/...\..................
|
||||
................................|.......|..-..../.............................../.-..................-..-/..|.
|
||||
...............................-......./......................|./...............-............./....../........
|
||||
..................../....................\........\...........................-............/.../..............
|
||||
.|||......../.................|.................../..\............................-......./..|...|/.-.........
|
||||
......-......./\....../.........|....../.......-...............|.\........-............/.../..................
|
||||
.....................-.\/|................//.../.........|.|......\.-..|.........|.........\..................
|
||||
.........................\/.......|.|............................|........|.............................././..
|
||||
.................................|.................\../..|/.................\.................-...-........-/.
|
||||
......................-...-.........../...........................\....\......-..-.......\.-....\....|........
|
||||
......-......../..............\/..................\..|........-..............|...-...../......|...............
|
||||
|.......|.../....|..............//.....................|..........|/......../................|................
|
||||
...|.|..................../|..../.-.......-...........|.....|./....\......-......-................|...........
|
||||
......\/./.|\..../|.|..|..........-....|...........|.-.|...................-.\.....|....................\.....
|
||||
......../.\......................|.....|...........|.........../.......|....|...|.......-......../......\...-.
|
||||
...|...-...||......-..|..-...........|.-.................|.................................-..................
|
||||
..............-.\.-........|......\..........................................\./.\........../.....|...........
|
||||
../\.........|...............|............|.\/.-/.................-....|...-.................-.....|..../.....
|
||||
....................../......../..../-.....\........................\..-.\....|....-.........../-.............
|
||||
.................................|................|.........|................../|.....|....\\............/.\..
|
||||
...///./.....\.................|/.....................\...................-............|................|.....
|
||||
............-...........................--........\................/.............-\................\.....-.../
|
||||
...............\.........../|............................|.....................\...-...\.....................-
|
||||
...\.............|.............|................\............\|...../...|.........................|...........
|
||||
..................|......|..........-.-..............\.........................\..............................
|
||||
....-................../.........../...|................/...............|./.|.../....\..../......./......//...
|
||||
...../....../..............................|...\../..........-..........-........-..//..../...................
|
||||
...............-......|......................|./........./............/..-...........|../.....-........-./....
|
||||
..\.........................|...-.......\.................|..............-........\....-.............-....|...
|
||||
.......|......|....../........\...........|......-........../......-..................../....................\
|
||||
.......................|....-..|........./.|.-...............|..\......\.....-.......\...-/....|/.........\...
|
||||
\......\..-.....................\..........................\................................../...........\...
|
||||
-....-......../............................................................../.\.......|..............|....-..
|
||||
........|......................|.............-....\................................./..\.......|..........-...
|
||||
...-...............|........./......\...../.......|...|...............\.../...\.../......|.....-.\......\.....
|
||||
............./.....|......................|.....................................\...||.................-....|.
|
||||
./.....-................/........|./....-......../......./..............\..................................\..
|
||||
.../..../\........-..........................|.-/.|..\................\\-.......|......./...||.......|........
|
||||
.....-.........................-...............\...........|.............-.\.../.|......-.|......../...-.....-
|
||||
......\....................|...../......................|.../......-..|............|......./.../.........|....
|
||||
...|...........-....................................../.|............./....|..../........./.....\../..........
|
||||
....../.../................\........................\...\....\......\............../|...............\.-.......
|
||||
./....\.../.............|............................-.../............../............/...........\...|........
|
||||
............................|.................|/..........//.........../..-...............|...................
|
||||
.....\......\.................|.....|...\-./...............\................|....../.....-..\........-....-...
|
||||
........................./-........\................./........-/.|....-.......\............-/\......|.\...-...
|
||||
..../../..|.|...............\.......................................-.........................................
|
||||
...........|...................................................-...-......|..................\............../.
|
||||
/....|......................................................................|\.../.......-...........-...|....
|
||||
......|.-.\......-........|.....-..|.\..............-......./......-|.........................-...............
|
||||
............\......................................|........................|.-...............................
|
||||
.........-.........../....\./....../.-...-..//.........../.......\\...........................................
|
||||
........\......../............./...-......\.../..|..|............................../......../..\..............
|
||||
--.........|.....-...|............../...|.......|..............\|............|.........................|.-....
|
||||
-\......./..............-....-....\...|.-........\/.\./............-/...\........|-.........../../...\........
|
||||
.\|\..............-......-.\...-....\..........................\........|...........-......./.............../.
|
||||
..........................|...\..../.../..........\.............-...//...............\..................-.....
|
||||
........./..........................\............|-.....|..-...|......../........-...........................\
|
||||
.......\.../.....\....../.......|..|...............-......................|....-...................-.|........
|
||||
......|.......\.../..............................-..............................|......-.-...................\
|
||||
/.....|.......-............/|.....|-......./..../......-........../..|......../.-..\..../....../...|..........
|
||||
............/..--..........-............\.......\................\........................../../....|.........
|
||||
..|..-................|.|..|................/.......\............-//.......................\..\...............
|
||||
.......................-......-..................|....\................-......\.|....\....|..../../|.-........
|
||||
........................-..................-...........................-..-................-................|.
|
||||
/.\....|.-.................................\..-.....\./.........../-.|..............\..\.....--|/....\........
|
||||
.......-..-../..................\..--|..............|...............|\........|...--................|./.\.....
|
||||
..........|................-.......|..................................................|...................|...
|
||||
-.-..|....-.|........-./...|.-.........\.....\/........-........\........../................./.../........\...
|
||||
..................../...|/......................................../............\.|./../................/\|....
|
||||
...//.........................\....../..............\../.......-..\....|......................................
|
||||
............................./..|./../.........-/..\..........................................................
|
||||
......\.....|..................|..................\.....\.-..\...../............................../...........
|
||||
..........\...........-..........-.....-....\/................../.................................\.....|..\..
|
||||
..../.\...................................\............\...\....|.................|.....................-.....
|
||||
...........-...........................\.......|-../.|....|.....|......................-...../................
|
||||
.......|.........\..............|....\...-......../...........-.....-..-...........-..................\...\.|.
|
||||
...........|.......................|....-..........\............................\.................../.\.......
|
||||
..../.................\.......-..|.................../........................|...............\...........-.|.
|
||||
............./..|.-\..../.....-............-....|..\......|......../............-.........|................\..
|
||||
...................\...\/......\............|......................\....|...................-./-..............
|
||||
..-\...........|.................../.....|....|............................-..|............\.............\....
|
||||
.|.....\....\........|..................\...............|..-/.........|.-/...........-............-...........
|
||||
.....\...../......-............|........./..|............-........................\....-......................
|
||||
......\......../........|..............\...-..-...|.......................................................|...
|
||||
...................|.................................\.....\...........................|../.|.-......-........
|
||||
..................|..............\.....\............|........../....../...............\.........\.............
|
||||
..|...........-..../....\.........--...\................../.............-...-....................-..../....|..
|
||||
.|...\...................|......-...........-\..........\.....|.....|..........|.........|....|-../...........
|
||||
.............\|...................../\...............\....../.......-....\.....................-..............
|
||||
.......//.....................\....\......\......\.........|...................../......../.........\......-..
|
||||
.\./.........-...-./-.\.............../......|................................\|....\...../....-..............
|
||||
.......|......../......../......./.........../...............|............................../..|......../.....
|
||||
............./.........|.....-./.........../....-......./|......-................|............................
|
||||
188
day16/main.go
Normal file
188
day16/main.go
Normal file
@@ -0,0 +1,188 @@
|
||||
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 Map
|
||||
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
m = append(m, []rune(text))
|
||||
}
|
||||
|
||||
rows := len(m)
|
||||
cols := len(m[0])
|
||||
|
||||
options := make([]int, 2*(rows+cols)+2)
|
||||
i := 0
|
||||
for j := 0; j <= rows-1; j++ {
|
||||
options[i+0] = runCycle(m, ray{[2]int{j, -1}, RT})
|
||||
options[i+1] = runCycle(m, ray{[2]int{j, cols}, LF})
|
||||
i += 2
|
||||
}
|
||||
for j := 0; j <= cols-1; j++ {
|
||||
options[i+0] = runCycle(m, ray{[2]int{-1, j}, DN})
|
||||
options[i+1] = runCycle(m, ray{[2]int{rows, j}, UP})
|
||||
i += 2
|
||||
}
|
||||
|
||||
// fmt.Println(options)
|
||||
return &result{valuePT1: options[0], valuePT2: aoc.Max(options[0], options[1:]...)}, nil
|
||||
}
|
||||
|
||||
type stack[T any] []T
|
||||
|
||||
func (s *stack[T]) Push(v T) {
|
||||
if s == nil {
|
||||
panic("nil stack")
|
||||
}
|
||||
*s = append(*s, v)
|
||||
}
|
||||
func (s *stack[T]) Pop() T {
|
||||
if s == nil || len(*s) == 0 {
|
||||
panic("empty stack")
|
||||
}
|
||||
defer func() { *s = (*s)[:len(*s)-1] }()
|
||||
return (*s)[len(*s)-1]
|
||||
}
|
||||
|
||||
var (
|
||||
ZERO = [2]int{0, -1}
|
||||
|
||||
UP = [2]int{-1, 0}
|
||||
DN = [2]int{1, 0}
|
||||
LF = [2]int{0, -1}
|
||||
RT = [2]int{0, 1}
|
||||
)
|
||||
|
||||
type ray struct {
|
||||
pos [2]int
|
||||
dir [2]int
|
||||
}
|
||||
|
||||
func (r *ray) next() [2]int {
|
||||
r.pos[0] += r.dir[0]
|
||||
r.pos[1] += r.dir[1]
|
||||
return r.pos
|
||||
}
|
||||
|
||||
type Map [][]rune
|
||||
|
||||
func (m *Map) Get(p [2]int) rune {
|
||||
if p[0] < 0 || p[0] >= len((*m)) {
|
||||
return 0
|
||||
}
|
||||
if p[1] < 0 || p[1] >= len((*m)[0]) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return (*m)[p[0]][p[1]]
|
||||
}
|
||||
|
||||
func runCycle(m Map, r ray) int {
|
||||
current := r
|
||||
|
||||
s := stack[ray]{}
|
||||
s.Push(current)
|
||||
|
||||
energized := make(map[[2]int]bool)
|
||||
// energized[current.pos] = true
|
||||
|
||||
cycle := make(map[[4]int]bool)
|
||||
|
||||
for len(s) > 0 {
|
||||
current = s.Pop()
|
||||
|
||||
r := m.Get(current.next())
|
||||
// fmt.Println("pos", current.pos, current.dir, string(r), len(s))
|
||||
if r == 0 {
|
||||
continue
|
||||
}
|
||||
energized[current.pos] = true
|
||||
v := [4]int{
|
||||
current.pos[0],
|
||||
current.pos[1],
|
||||
current.dir[0],
|
||||
current.dir[1],
|
||||
}
|
||||
|
||||
if _, ok := cycle[v]; ok {
|
||||
// fmt.Println("cycle")
|
||||
continue
|
||||
}
|
||||
cycle[v] = true
|
||||
|
||||
switch r {
|
||||
case '|':
|
||||
switch current.dir {
|
||||
case UP, DN:
|
||||
// pass
|
||||
case LF, RT:
|
||||
current.dir = UP
|
||||
s.Push(ray{current.pos, DN})
|
||||
}
|
||||
case '-':
|
||||
switch current.dir {
|
||||
case LF, RT:
|
||||
// pass
|
||||
case UP, DN:
|
||||
current.dir = LF
|
||||
s.Push(ray{current.pos, RT})
|
||||
}
|
||||
case '/':
|
||||
switch current.dir {
|
||||
case UP:
|
||||
current.dir = RT
|
||||
case DN:
|
||||
current.dir = LF
|
||||
case LF:
|
||||
current.dir = DN
|
||||
case RT:
|
||||
current.dir = UP
|
||||
}
|
||||
case '\\':
|
||||
switch current.dir {
|
||||
case UP:
|
||||
current.dir = LF
|
||||
case DN:
|
||||
current.dir = RT
|
||||
case LF:
|
||||
current.dir = UP
|
||||
case RT:
|
||||
current.dir = DN
|
||||
}
|
||||
}
|
||||
|
||||
s.Push(current)
|
||||
}
|
||||
|
||||
// for i := range m {
|
||||
// for j := range m[i] {
|
||||
// if v := energized[[2]int{i,j}]; v {
|
||||
// fmt.Print("#")
|
||||
// } else {
|
||||
// fmt.Print(".")
|
||||
// }
|
||||
// }
|
||||
// fmt.Println("")
|
||||
// }
|
||||
|
||||
return len(energized)
|
||||
}
|
||||
50
day16/main_test.go
Normal file
50
day16/main_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
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, 46)
|
||||
is.Equal(result.valuePT2, 51)
|
||||
}
|
||||
|
||||
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, 8098)
|
||||
is.Equal(result.valuePT2, 8335)
|
||||
}
|
||||
|
||||
func TestStack(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
s := stack[int]{}
|
||||
s.Push(5)
|
||||
is.Equal(s.Pop(), 5)
|
||||
}
|
||||
13
day17/example.txt
Normal file
13
day17/example.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
2413432311323
|
||||
3215453535623
|
||||
3255245654254
|
||||
3446585845452
|
||||
4546657867536
|
||||
1438598798454
|
||||
4457876987766
|
||||
3637877979653
|
||||
4654967986887
|
||||
4564679986453
|
||||
1224686865563
|
||||
2546548887735
|
||||
4322674655533
|
||||
141
day17/input.txt
Normal file
141
day17/input.txt
Normal file
@@ -0,0 +1,141 @@
|
||||
222343122415245553243251316124223234134666332224124211645376775672443247264263475261513546522316162532215534453661231232515522214351143451211
|
||||
422125443253354142511545636246664666565355152246453231651172747635424163415626462753445445312334225221624336126244661514234445544425223533122
|
||||
131212112421423414125516356342555542626661163526211536677376523712262371162153644117776261645533664544366146314432523222515425314231311544521
|
||||
131334344235153415214541223454455223563154114267331524774136127715554416125273543276346471735741663351266324144422511534542234341513351345352
|
||||
314541545523112111131565114333211153312641614321771374726154434476767125613311254537363422511721275135434164664442151263234241114111121141334
|
||||
435153335153513534132112326653656626231351436457153446433363235565156156723233715473535244413451723176561153261562445512312413413513135513241
|
||||
235243535523134543445216214455445352435554624255171271225755313626173154112144673146273747537614771377613244145436355342536323123434425211113
|
||||
132552152551514515631323412533333446136243376366556365574745474652757277632216317677316551253673465513776336664225626313216456312542531241352
|
||||
311415311541314143614162642634556464574541744355655753776632763662153656721435137347422375344242225276244673434333351454464536453212424421425
|
||||
453351344131342126143165264626543453632747531417235617257564537542611276314542732241535726557435722271523761452243145343543365433423153132344
|
||||
424354321333252642533513531241416236636427325176724425161362563217173773414665312244155777552374513335344162564462411154332652126231133233331
|
||||
433224533551436134314641523151361154615353522622137441214134673454347752343853221756746664765556521762762464233333523123643145626644231443435
|
||||
243311313556533564523443331214721572253144611715156456321767676655457736255732864573164467712433421256325731135656541255561161224441152415141
|
||||
511211214252345356344156642436611545463224342452742717585325436325574336455336582448256836717741726221177352616311422112513255165441212221131
|
||||
244253443163544142511413446172632624762126756145146775348573476557644782564438437852836725866452746165474553473737534665123425113435563332453
|
||||
232155346345514313654314235557517112176174776332136456448427547478426265844263882743533766568854547675464477171376662424251312612162632514355
|
||||
424114441642564135264345176163444365144163124128832285838626688224834432458556377773645427653638562736676174576737574642156232566466636441124
|
||||
543244331213246512421551417132132647763461226245235583478358556478588445828784366325778587856624776125647332126411416416253326543252561355453
|
||||
513411632124243263566153173255453461117356682265475822242236525286334354628536868726586284535383867467645552277715213631624352612331534144225
|
||||
234513324414264131211345613416736552211115685767773523645885727834464346536233245827443237753783724626566246761647646475456131431415434413214
|
||||
132312323255146664114745115275443572754326543474673247542856435836784453584863735676475556838547655484787272216413226712176641452341133361621
|
||||
324445311115236332563161165371142354332783687877726543524347444677384655338335874866474624655543543466338566764524432633543363631622335214314
|
||||
452146561262254136627644671525514257523265444635773245326674352228844844533536247443486645863647324742823822411266212747246263222143515531123
|
||||
323443456261326564347757145611113632534754323645837762327643383533554795688333775647234446628482555868382485343642524356327477353226234131236
|
||||
323566623463524644662155345214734554448367587534458465333783778836737748873896436675564776876254472473382773351746477537426351164321556552155
|
||||
411624314463555226413151162214157826642348553426375774773937688356445778864665387877397647688288645648488526683635462551221145364643422311353
|
||||
632541423444624336526576464457777686224586376437338832948677343497666833369685846994446858346385546773453274862246234173462724342631561154224
|
||||
353552612514333121215745416727247272652423544685753368594647394695658845883548858535734584333432476287445274435882257755366724515216151451335
|
||||
532166314441574113623175262414284358754786632434337878589943898388748395969493754638344944356356855723827482463322173565111471477266643531656
|
||||
116644351623354144151425116542234543365536844644456554366885339853375594997998864974865377578863643354482658652565456654732562467462642222633
|
||||
425265565534525427323521564886284475834357765873953575557676864375449896735695696945686539933897587748627756658646775714547636543542445454453
|
||||
535223341313647443711526456446656284686644344893747447894898636684595668686646634379736944587367734766868686525582828566224141647377452234555
|
||||
363661154543263115262561162483434662346246798873478436638737549697754638834495375733735333645433574877375276735684662372751455123234415466135
|
||||
233425541263155564422777566657463284532222644739657858356574964435535676435594635788954898867344838753677578547362236357265747553176223645334
|
||||
516113313346251471245336736766463235445577574763999559496983357388779634999695985559489635746544658453383775634426265623615715313624324613363
|
||||
325162436525537742416463226466422582452664444569687695737766869564846698477563438574369658749388443473974527623665566388541124766765465414216
|
||||
246532424466452274271137247462733834328375758733755764656833968984956876697799766884997394499744585594587876625677723447244217267426213343664
|
||||
164356325132241765153442235356485242287535595375398869579646888545895757975449659944533834737579865398575662388572336243423321763313272155166
|
||||
563615555622724634724833866443433524894838958833799835363644977657658578544664475868679458747866349983337933858733558557637772576116524351364
|
||||
415635136113175137578553536586564768643559866697595733497557879468449998976698759797676436636689587877974934738258785642847435574452213713115
|
||||
611145153512463742256332755487858466583796497738685664885658748948569545664445888744947857868589779795933867483673776857358564657524755764663
|
||||
235565633417713142257732254688636564985938796475899556649457697557496557466787887559566976984578789695478656638728764846466352277661663613361
|
||||
621414363456434251274757622526573747939964946885796964745598945469487687577499977988878866574434454755956575894225366755752223145132155653231
|
||||
345131227736331632753528624737877993467633874573544566489488585879587798745544677645759486797999989373758553748378762622865225676664655255241
|
||||
211147374365347566347683538644229836375367399779966469889799674657475784657559849567645885568589949973844765649576234674566626355732735375222
|
||||
123377577423217135757464227844458664877347575684876765589445958984848645558957589999985649678755757487567997496322362828232445742466637677526
|
||||
664165716524474573468574845478963396633746335989586478477469677874488696466969855457589699479795777786993453995866655558838835473455711456363
|
||||
645354217411347423778226725287476938984748595969986859957845897656645797969945967774756979786597495489759753559534884668577746471267563715146
|
||||
641123731653617153523878786635997676839634584755798896844786989789997886975976877949768456676679545757849946967975863276534664727276625714772
|
||||
115172313432542554343534322666684547383747359496846665858866986576677885977798965677465955688547658777937483437698822255673227856674321437423
|
||||
412316124234335666538374784464654983653484498444688865778477997658875656978599866558669858496479969969883747883595375635748886535531163731666
|
||||
126215534552633672772444476653659865338587448788645985679486758768567978966789759768556688875958549895757653789978826784367383554244325537527
|
||||
252471722164728674273366346869733763887789597776444684764998985757556667899857586887855996664484555498483585754587755247628423684671244526734
|
||||
616643241174113524686752733973994433637977478579974486858559967566675596878985789668957757945476696698659695977366876442282382768473657366141
|
||||
433715625621658365787576378559966694694594565764577974766866977599956779776859687775695787565694987685963787977966448785772368444344613132341
|
||||
542654365337336826434765643879738646353964647955974749776876686976656857777555965796959755779797949695874357763646457888473355582731254116326
|
||||
461216754736354442526774233456439439344649448885449769679668978899596596779679669865776767595846454969558697477357393642534444663773547743151
|
||||
242515737157657333842228548349875463457585648494866999577597668698587656558567788999587689857767876885764484449548964773473277753231345166735
|
||||
654521345226446835568566235799768737539786475876888887965595966585598966967969975867759665599758868667576445864433979732538253832712175534524
|
||||
115512724255847238822523769738898864344596868468594857859588665686578579798878998656799555798598889485694534558457599364226342568753677472213
|
||||
111524524557584843753648338688446565566879945758747566968678858898688798787995576956865896565768766698768659698554344826255288878683415552615
|
||||
775523534424885336584535598468769386864885649976596679699998877966986778776767559667869889767766556949956568378399476985828735885425764761532
|
||||
617234235723887272453554398456849533986998847969886896697596899979688786876777696866697569685659688446949473894494359678374775655237573674227
|
||||
731315731775542663287374348536374735499748575465485866966768699899697997797776666566989778755777686999847946948853933693544267753841326646546
|
||||
722426246522232587267567746363433367778759685487558796666966958776698867986668698666876866775886659846776955633755765593638285378256357434712
|
||||
174725351666826552875547497865663863549888789874668876958895676696978768897788786788566955869997548858768874638777786742243328886625132571731
|
||||
611354237262464432722652894576534365759676599966965877965957687768769888968769696957679665987557457444944459839769348686383583662783465636276
|
||||
435775645554577458385385799454458446877466964957585556758766679978876698869886969697899756896864788684659949467367797467452464686586746747527
|
||||
326715157438852348356648795697795987947557758498877979757678677886679987996677668886868888557795864545877549896579885386328386465786533157726
|
||||
453273273424255488663856445483976736667859995777897779896656697978997888787987898778776958957796758748894869487957534497554376546868722122324
|
||||
224573216435873475783673336556553645879964994546857977556976898696968678989979687688777875655579994576659674597887987885384834758677414425113
|
||||
356241135726344637684746374354974769468887978766569659956588999669799779786678667886579699675678884889486587434679643859352582448655434457222
|
||||
466565323122567376356874397989745956794895966548765989989778688799697678896789997978696969665976575677558444868875986457762338452225134143337
|
||||
362264215456463347238855743779549969969487765646768855768895876877976886666866799968989767688568764586578687569679978449782326532643416155546
|
||||
671362724447463788282378857469553747694544454845755975585656699878677799678797776968799697957896898878765444867363549353272748888443452166364
|
||||
632542654733754847425787585687488755596748847964799999775985798869786789699666867675565568797969676665954954838875438688564548862244145146171
|
||||
333723417316447367476286584684499973896998895898557855668598997699996977697796768788767776689759949696664864687338847464274357245662617625121
|
||||
732722335132788573566373398994377893654688989578766978658865988697879899789898877758688978567997675756877983739477395738266566365866553224517
|
||||
147177514747474242267782783587784747967985778647866665897959877679967669667689876857669669767556998597597497483549887695587764775634662343617
|
||||
152744472376652374322667687839455953897495766449899756875956679668789688868676978978876787578985556849965685833354883453248267842384616432657
|
||||
217227543612352346346455856939488455758985798868598588765697888677977868879697796686766696678556576857569777547694747435272652536672167123712
|
||||
744625215616674868776537785459394998859647888485449778786556769796876987889777989756758976977758496584958578978633843394583557326773745211217
|
||||
353354332722486863626455784779737558677796677557648786868756998567779997999757769989968679778794444858495938377534839655447657354377534537617
|
||||
351162251452745473452566496983484689397949849568679798775655588857855767769795678968695766898846549555848585493436735966444566758545364773274
|
||||
546334341147183722785558798496869978864895677895756565879578585766957665575757696669676677769768545948765446463585354842584745473612425647573
|
||||
235615763364478535767825263879546994497978874484569465769576969857869669765659777668868977865946966479776587987999955433355672374557554754214
|
||||
162177325222163583735436483646438894396659587698644456886655596959879587966867768858997789444759867989565846639353845278562446263633245724416
|
||||
324535255452483383635664425784958857579867676497445879975595969977679879855779697798889657664476857564676937793853344868547244368834643131142
|
||||
121347276513238722442368557665693779499584456766988769868757758795788956896585869778678687556788794995887699638544336543625582864246234111541
|
||||
357771157266317334828437783465549356369747964978875778866775965679685977988796799568586768676664767564576835757749675276226376757244531177246
|
||||
336664616327762746632336856333359783983467896468668468658857596888666655696975568657694759566847599666396674475446532283582787232143364371132
|
||||
644533212754142233635788744897443835653636699755644785889878558985567878858696858779788657475547995487649399794638387758824355331366214575725
|
||||
222217676717612667687783367437478679946969645869469768494864887557985785659965856994457654994548995554598868743539788752855264561637271324324
|
||||
356452154463414577848785374339498366535638544946846765677495769785557579699659788879447959897745467466459849543743454246822537753427335371562
|
||||
343351256333451586862433643627656985753774749546555768998795848687576559887698545798748988498774696693748665338953758884323743215516455337651
|
||||
511156433162323673647444877388393898578477588665844949845684789786485757669794987664595874795599974455755347864958728824643583546532455523751
|
||||
156124537652656126446766564883685565845949468648655489495444579455874554846945778967786444756587898964737436487344256846452377111452125151424
|
||||
515264356113762652852852632686537484556764597765774578755556886965448899978985694964457598494775673883444869546887836668355228143455736361562
|
||||
263512646525146141226625365446528679473694599878945468469659775468694555669548954648468546665655847884688365888823562232347546127534712221733
|
||||
631415241711525626678448673422265459959576695493999586674865475767744965494946497644686744965594334353963643655244478563353652375272512755651
|
||||
233341711151632262167275682837682337594668593834657957999678754665457846558698875995554875885564465558544593484682334467458266753354353656363
|
||||
222614621174264456548568855775763264556684446457483755666594465554896878549965797747587445795345639937745754468637877328233727712145444373316
|
||||
551136576466563613374865837744634548656596546959875864946578986489646467467887584454698786369755639588797883757583882864432762672266561742114
|
||||
311433545766254471655428367633528758869667674337353886355568568977559794557448545869856978986385835684993879575657778365536445625371464633155
|
||||
223612464456771261577683747465843843667648368983574634838577897765496687876598844667977633334687854753563787465237347324763236171472235426346
|
||||
411245121677351625555347323585443444334598696449339998397379788744556985684748696646376458494657966586849537253887746577841254462522431254352
|
||||
344346233632636772414765673728476885836598589955558748979779588656646877576889768598337348786569379345443684386546372358847445714773517622512
|
||||
155323536362462251246768675874228887274856495665585569666835536867574987794867838438565638693854398377677783434776265675564455312663443423541
|
||||
331566446775752674417132753235465665833378447847639386878845593445734945386694688999635777683567968539426228468486664337643254264256612362121
|
||||
243564654224225645722672382353864676463257496747548887493585987546678658735985743376384577953533946647357564447863573451724364472125432653566
|
||||
342315614225414552353574355435638346877654437484463854837898965395385547754648364866393337683989446882326338262227448314144441743477561422165
|
||||
513316635431624236671443348277886572254832458877847668477593794644585888563857755634797589885668862754772785358487877315135613177367144545513
|
||||
463143244643262172563515774358878556748352525757567987986693359853994963575439443448643467386743366524235883462535432614464455735443452664134
|
||||
365641135114444646623465131227245648484522527682468766639838853356859443957586854538395483886846572325432336737857272623363152162131551135414
|
||||
416313341334271754356764361744638674522648825426627539586358437534848469663986377869797354638474474353788632454247175546246417444136416435644
|
||||
224353155431264253763746646441542886447853826453463553364576374757797585985553484899859547773742768633328427884282476754133441524461616242643
|
||||
141663652631255115673535171111246265842334873322667887864398959494389595436394448689564435578232373254536888873517235136312276614212451451513
|
||||
124131511566566612435515461237554545678463532355284383577958338477334574565899548354995646534573786226335788675417311262514713363312364535154
|
||||
423124641651141434731445642547213258886735546328578275442562699767675575457466479427885838355373878586875834224154546773247146645646322335264
|
||||
412644326632526437735316412561445417468882886666655743427476665574794946797787288666754744722668682487625266217525212752446411411125122652443
|
||||
533453646465125514654252753512273714342227373732733663723654553522224855828427587263828376724486786422622551345652174733731235533661345526462
|
||||
431416626556561415256423726364711356216462533453778624228776264745488556248346558664685886255267664468734267241413666377354236365315112133322
|
||||
115242144546551242654657115464153653733572255453735867582743877872748475375858445224247557346684865447435434415136572343667245436453541641214
|
||||
211445545143351463615353774344215444543156828652686467572385233427763332873666832447256386848435536242337137777716372765516254142315334335233
|
||||
345124663224645321264314114673647256557756426376735374628552375257437773764536467386624358238642865332573246663566211211655655563524242452555
|
||||
314351264524343426135362454521352527263736457447533445374485277766767738682474542365754582457568722614424111744153725635141565436222616112315
|
||||
525142531331665442641251651451342365334554162254374267466577736465886625773232626738363773743786773241666727445735231415436342625513255235151
|
||||
543245142256442454155334231734217734761146755176638778856523266374354672783363252424683478557527343237227211135754547531342136551132351221533
|
||||
241355115114515145351235241342577311663523713245571552423844478483444456674576776374774635321762611146175633416417526461446534624524525232351
|
||||
413212231435125464562416642131514721163172662635774761555772466528432746222877628357558463622434577676277711461224526611415645224221334321153
|
||||
424114552242412235261232556412366663124614547557116436567672766285253724382874567666431356536715216512355113511563132462412461555112225422135
|
||||
322324544333135432235125224253374616723165212337472223432464246434784434268261665524555163346167575177573432151165141342526636661664333152245
|
||||
533322454514225135644666511564116113743567665217446774461763723457213436114546254524754413534661176555531123216654634336153535555615455221351
|
||||
345114245113253556125335351622625171466165175642167753751336711273734343723253343654164414153211641676412352766561245653215262351455523141451
|
||||
142421541514212154334545211465656444644552463442357616615277117635256363621723512341776351424463622726131565431516465664346151153212233245553
|
||||
444314343434312135211364665242441535527647475416223551347736416724264751235567161762631557147415445546211321423221136662344161541525343455425
|
||||
513343214231252255165411335621632642146147645756642561211667322537371252122672641421372561555336143123644446534414131135624333443543522413531
|
||||
151133414553422411155141354122545416221132657162133367556711163132611352466177573117122527412137673543111622364234433423115531533515415532534
|
||||
344341433553215433332561124312211661162315615567541645475225431414323527474442612165214546553775576346352241352363416414626442233143123431324
|
||||
312334123334252355135521123323245125516132154636463653576675247514555746177477533534522123547665145656414436131454466514531422525141331441324
|
||||
221234522113214232242154165523542235561622643243233434644217742623556626525264626677654256257462621433131425222466152534235213545112335523443
|
||||
225
day17/main.go
Normal file
225
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
day17/main_test.go
Normal file
41
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
day18/example.txt
Normal file
14
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
day18/input.txt
Normal file
766
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
day18/main.go
Normal file
89
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
day18/main_test.go
Normal file
42
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)
|
||||
}
|
||||
17
day19/example.txt
Normal file
17
day19/example.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
px{a<2006:qkq,m>2090:A,rfg}
|
||||
pv{a>1716:R,A}
|
||||
lnx{m>1548:A,A}
|
||||
rfg{s<537:gd,x>2440:R,A}
|
||||
qs{s>3448:A,lnx}
|
||||
qkq{x<1416:A,crn}
|
||||
crn{x>2662:A,R}
|
||||
in{s<1351:px,qqz}
|
||||
qqz{s>2770:qs,m<1801:hdj,R}
|
||||
gd{a>3333:R,R}
|
||||
hdj{m>838:A,pv}
|
||||
|
||||
{x=787,m=2655,a=1222,s=2876}
|
||||
{x=1679,m=44,a=2067,s=496}
|
||||
{x=2036,m=264,a=79,s=2244}
|
||||
{x=2461,m=1339,a=466,s=291}
|
||||
{x=2127,m=1623,a=2188,s=1013}
|
||||
780
day19/input.txt
Normal file
780
day19/input.txt
Normal file
@@ -0,0 +1,780 @@
|
||||
ztj{s<2703:A,m<1025:vk,ztl}
|
||||
nqt{a>3513:R,s>2424:R,m>929:R,A}
|
||||
mr{s>2281:R,A}
|
||||
gf{x>2746:R,a<3379:jcl,R}
|
||||
gkv{x>2579:qlx,s>322:rxv,R}
|
||||
gdl{x<2917:A,s>82:A,s<54:R,R}
|
||||
hzc{m<1277:R,m>1355:A,x>953:A,R}
|
||||
xs{x>2337:ft,m>1444:A,R}
|
||||
hs{m<235:A,a<2424:A,x<3026:pvh,hqk}
|
||||
cls{a<1361:zch,s<3630:tnh,a<2359:px,spb}
|
||||
gq{m<1157:A,R}
|
||||
hc{m<2726:A,s>1302:A,R}
|
||||
lt{x>3157:A,a<3669:R,R}
|
||||
sf{x<3199:R,s>2680:jrl,x>3718:jh,R}
|
||||
hr{m>1737:A,A}
|
||||
bgg{x<171:A,x<283:R,R}
|
||||
pgb{m<1624:ksc,x>2675:bzc,bzn}
|
||||
zm{m<2599:sjc,m>3497:A,m<2946:A,A}
|
||||
gbb{x>860:bxv,a<2306:br,msc}
|
||||
gsl{x>53:A,A}
|
||||
zs{x<1669:kp,x<2690:ns,s>2951:cls,tvv}
|
||||
qhq{x<1264:A,m<1728:A,R}
|
||||
gg{s<239:A,s>340:R,x>3642:A,R}
|
||||
ktx{m>2620:R,m>2073:R,a<3539:R,R}
|
||||
xg{x<3497:fp,sgc}
|
||||
pms{m<3366:R,x>3570:A,R}
|
||||
gsb{x>2077:A,A}
|
||||
xf{s>3779:A,R}
|
||||
tfs{s>3844:rb,s<3703:scg,bk}
|
||||
bgb{a>2837:R,a>2812:A,A}
|
||||
nvk{s<2358:mr,x>2818:nqt,x<2757:lf,R}
|
||||
fg{a>1961:A,x<68:R,R}
|
||||
cfz{x>1567:A,m>951:A,a<2959:R,A}
|
||||
ljt{m>950:A,m<557:R,m<745:A,R}
|
||||
zcq{m>1403:th,fd}
|
||||
tbv{a>1532:R,R}
|
||||
dq{m>960:R,csz}
|
||||
tvv{a<2619:zh,m>1623:kb,vh}
|
||||
dzz{s>3136:R,s<2702:A,a>2889:R,R}
|
||||
lg{a<66:A,s>784:A,s>263:A,A}
|
||||
zfk{s<463:R,x>3180:A,R}
|
||||
bdh{s>356:A,s>193:A,m>482:R,R}
|
||||
tc{m>3454:R,x>3211:A,A}
|
||||
tz{x>3191:R,a<1319:R,R}
|
||||
cpn{m<2478:A,a<2228:A,a>3262:A,A}
|
||||
qmt{x<2144:R,flt}
|
||||
nsp{m<379:R,R}
|
||||
sxt{s<1011:A,a>1135:A,rl}
|
||||
bjg{m>973:lz,x>243:hh,a>1789:xl,xmg}
|
||||
cj{x>2137:nst,m<3002:A,s>3193:jc,pfr}
|
||||
lmc{a>2967:A,A}
|
||||
tv{m>1493:A,m<769:A,R}
|
||||
khc{m>2346:mbr,s>596:kvr,a<274:fzh,tb}
|
||||
zbk{s>1140:qrt,x>1818:pv,a>540:gt,gxc}
|
||||
kk{s>3728:R,s>3683:R,m<562:A,A}
|
||||
jv{m<848:zpq,a>1225:fsv,ztj}
|
||||
shb{a<242:A,m>2625:R,R}
|
||||
fhg{m>1372:R,A}
|
||||
dg{x>1246:qd,s<3289:lbf,a<1032:zzp,ks}
|
||||
cfq{s>2689:A,s>2613:R,A}
|
||||
gl{m>2798:cqm,s>3029:cnl,m>2233:A,qc}
|
||||
tkv{m<1884:A,A}
|
||||
fdm{m<1549:tgt,x<2498:kdf,s>528:jz,lt}
|
||||
vx{x<2948:xc,mgp}
|
||||
bs{m<687:A,R}
|
||||
kp{x>609:dkr,tqc}
|
||||
xpj{x<934:A,a>1772:A,A}
|
||||
rhd{x>956:A,a<2471:A,a<3414:A,A}
|
||||
srg{m>1381:A,s<264:A,A}
|
||||
szv{s>453:mff,nzj}
|
||||
ldl{a>3906:A,A}
|
||||
rxv{m<1632:R,m>1700:R,R}
|
||||
ch{s<3588:A,a<639:A,R}
|
||||
sc{s>2789:A,a<1419:R,R}
|
||||
gk{m>415:R,x>508:A,a<3053:R,R}
|
||||
rs{s<1893:R,m>2997:R,x<2049:R,R}
|
||||
ncn{s<722:R,m>3562:A,s>773:jm,vr}
|
||||
kz{x>3160:A,A}
|
||||
xxt{s>1035:R,a<942:R,R}
|
||||
pfr{m<3520:A,A}
|
||||
nh{a<638:mv,s>865:vm,nrf}
|
||||
sg{s>3051:vps,m>2918:A,zhs}
|
||||
xnj{x>3494:A,m>584:A,a<1897:A,R}
|
||||
jg{s<2380:R,a<2211:A,A}
|
||||
cqm{s<3107:R,a>3295:R,m>3224:R,A}
|
||||
hgv{m<203:A,s>107:R,A}
|
||||
vqt{x<2609:xkn,bnt}
|
||||
ft{s>3154:A,m>1087:R,A}
|
||||
qv{a>621:A,a>259:xp,m<2439:fbv,kpq}
|
||||
lzv{x<2186:gpt,lsb}
|
||||
lx{x>3655:A,s>2359:A,s>2271:R,R}
|
||||
xfj{s<407:sxx,R}
|
||||
tnh{x<3164:vx,js}
|
||||
mbr{s<671:A,R}
|
||||
tbn{m<2151:A,x<3001:R,R}
|
||||
zhp{m<3768:fgp,x>3307:rv,kj}
|
||||
qd{s<3201:A,s>3491:hgt,x>1468:A,R}
|
||||
qdk{s<1950:R,R}
|
||||
vn{s>2814:A,m>386:A,A}
|
||||
lv{x>3090:A,s>2406:znh,R}
|
||||
km{m>2029:A,m>1871:A,s<2456:A,R}
|
||||
ppc{m>2718:R,x<2889:A,x>3361:A,R}
|
||||
bk{a<3189:A,m>846:R,R}
|
||||
ht{s>2582:jts,x<3333:hx,rgx}
|
||||
bb{x<3122:A,x>3258:R,m>3625:A,A}
|
||||
fd{m>650:R,x<450:A,a<2254:gb,gk}
|
||||
dcf{s>1084:tzp,gbb}
|
||||
pm{x>3659:A,m<3539:R,A}
|
||||
hj{a>3260:hrn,A}
|
||||
ds{m>767:A,m>718:A,R}
|
||||
ccv{a<2781:R,a<2905:hd,s<1781:A,qdk}
|
||||
vh{s<2473:lpg,m>643:cmn,s>2647:vkk,ht}
|
||||
zld{x<3737:A,xst}
|
||||
djf{x<748:R,R}
|
||||
jfx{m>1768:gz,m>802:jfs,m<437:cl,snl}
|
||||
vft{x<2121:dn,m<2486:kf,x<2180:qmt,vsj}
|
||||
bc{m<369:hs,a<2050:dfd,m>584:mx,vqt}
|
||||
dn{a<799:vbr,m<1868:A,s<1387:skb,rs}
|
||||
kxl{a<1795:A,s>3664:A,s<3514:R,R}
|
||||
bh{x>3971:A,R}
|
||||
pv{x>1877:R,s<517:R,m>2313:R,A}
|
||||
vzj{s<1879:cth,vc}
|
||||
fc{a<2156:ths,zbc}
|
||||
cs{a>2745:A,x>2067:A,s>2357:R,A}
|
||||
nsj{a>2800:A,m<2010:R,R}
|
||||
lsb{a>2810:R,x>2463:A,m>2877:R,bz}
|
||||
nl{x<2336:A,x>2529:A,A}
|
||||
pk{m<2800:A,s>3027:R,x<487:A,A}
|
||||
bzn{m<1838:R,A}
|
||||
qrt{s>1765:R,s>1529:A,s>1302:zdc,kzp}
|
||||
srn{m<3131:zbr,a>3269:phc,x<2610:R,xd}
|
||||
lz{m<1282:pzk,s>1085:gld,A}
|
||||
spb{x<3144:krj,sx}
|
||||
mqz{m>467:sm,m<282:R,s<969:hhs,jfp}
|
||||
mff{s<632:A,x>625:R,dzt}
|
||||
hgt{m<2577:A,s<3667:A,s>3805:R,R}
|
||||
xpv{a<3077:R,R}
|
||||
rf{m>3497:gv,a>334:vhk,A}
|
||||
rsc{s>1811:A,jk}
|
||||
vkl{a>1095:A,a<912:R,R}
|
||||
mpn{a>3161:pdk,x>3461:zld,ff}
|
||||
pzk{s>1180:R,m>1114:R,x>299:A,R}
|
||||
vf{x<492:R,s<3334:R,R}
|
||||
kjv{m<719:bc,vhc}
|
||||
ks{m>2088:kxl,a>1906:ll,gq}
|
||||
vm{m>1632:vb,qcr}
|
||||
ph{a<2292:qzf,A}
|
||||
xn{x<2461:qln,R}
|
||||
px{a<1762:xg,x>3186:jfx,fc}
|
||||
fzz{x<3174:mq,a>1103:nn,m<533:bgn,mdq}
|
||||
xl{x>116:lmr,m<712:nvq,a>2807:jmf,R}
|
||||
br{s>958:xxt,x<537:bnn,a<1228:R,ssr}
|
||||
mcl{x>3441:R,s<2530:R,R}
|
||||
gn{a<3598:R,a>3777:A,x>861:A,R}
|
||||
scg{a>3029:A,s>3661:A,R}
|
||||
kr{m<471:R,hz}
|
||||
xfc{s>3354:R,R}
|
||||
th{a>1860:vf,a>789:pk,mt}
|
||||
nm{s<2242:A,x>3062:kz,R}
|
||||
xp{m<2732:R,a<441:R,A}
|
||||
fzh{a>101:A,x>3191:R,A}
|
||||
bn{x<3725:R,a>499:R,R}
|
||||
kmh{s>1727:A,a>1678:A,a<1550:A,A}
|
||||
dj{m<2927:R,m>3578:A,x>1056:R,A}
|
||||
jz{x>3123:A,a>3678:A,x>2902:R,R}
|
||||
qq{m<3557:A,m>3852:A,a<1950:R,A}
|
||||
nrv{m>1238:qcd,mqz}
|
||||
pmd{x>3502:R,gdl}
|
||||
ll{s>3570:A,s<3419:R,x>946:A,R}
|
||||
td{x<1875:A,a>1161:A,A}
|
||||
jt{m>1937:A,s<430:tkv,R}
|
||||
pp{s<1233:mzr,m>2932:vsl,ccv}
|
||||
ssr{s<903:R,R}
|
||||
qcd{m>1677:R,R}
|
||||
sv{x<3042:fv,s<3775:tc,m<3706:ct,dm}
|
||||
qsg{x>3287:vvt,dbq}
|
||||
cdt{x<3342:kx,a>1677:btj,nth}
|
||||
jrl{m>1242:A,m>940:R,m<793:R,R}
|
||||
dzt{s<732:A,A}
|
||||
dk{m>1342:rmq,hdt}
|
||||
rn{x<3645:A,R}
|
||||
fx{s>1211:jpn,s>785:nrv,m<1357:pd,dcg}
|
||||
nvh{a<2086:kmh,x<2940:A,m<2730:R,pms}
|
||||
cb{x<581:sd,psf}
|
||||
mq{m>678:A,x>2970:qf,a<881:A,ck}
|
||||
qfn{s>298:A,R}
|
||||
rss{s>1618:rsl,frj}
|
||||
sp{x<3759:R,a>512:A,m>3807:R,R}
|
||||
dns{m>270:A,x<2335:R,s>3567:R,R}
|
||||
dsr{x<2503:R,m>969:A,x>3358:R,A}
|
||||
jfs{s>3760:R,R}
|
||||
zpq{x<2139:td,s>2466:nl,A}
|
||||
vk{s<2893:A,a<803:A,s>2986:R,A}
|
||||
rbn{a>3902:zp,m>472:A,R}
|
||||
tvn{m<2544:R,A}
|
||||
lqf{a<3601:rnx,a<3691:A,fz}
|
||||
ls{m<1384:A,R}
|
||||
rnk{a>3786:R,m<2367:A,zl}
|
||||
pdk{x>3398:R,s>2636:tnq,a>3510:xt,km}
|
||||
gm{x>1475:sg,zdv}
|
||||
ps{s>2886:A,A}
|
||||
ndh{a<979:fkj,a>1636:A,s>2743:tz,nf}
|
||||
zhs{s>2501:R,a<3309:A,s>2306:A,R}
|
||||
zht{a>1418:A,A}
|
||||
fn{x>3198:A,a>3957:R,m>3278:A,A}
|
||||
xc{m>1714:xfc,a>2574:cmr,A}
|
||||
gld{m<1414:R,x<381:A,m<1444:A,R}
|
||||
pz{m>3006:R,A}
|
||||
fkp{a>3424:R,m<3526:A,A}
|
||||
fqc{a<2473:tv,m>2350:cj,a<2565:xs,vv}
|
||||
bnt{s>1011:R,x>3453:A,R}
|
||||
xzq{a<3766:lqf,a<3888:kgd,s<1399:zmt,lp}
|
||||
clh{a<1003:A,s>3818:A,ntv}
|
||||
rq{s>2799:R,m<1088:A,A}
|
||||
jfp{s<1113:A,R}
|
||||
hh{x<466:A,R}
|
||||
md{s>1194:R,R}
|
||||
hm{a>1759:gsb,R}
|
||||
vb{s>1454:A,s<1082:kxs,a>1134:A,hc}
|
||||
rsl{a<3803:gh,st}
|
||||
tjb{x>2545:A,x>1949:A,R}
|
||||
zsp{s<3356:R,A}
|
||||
bg{x>1362:A,R}
|
||||
lbf{m>1460:A,mnr}
|
||||
bt{s<856:R,s>1189:ppc,x>2845:R,R}
|
||||
ct{a<1119:A,x>3291:A,m<3487:A,A}
|
||||
drn{s>2455:R,x>3658:A,x>3401:R,A}
|
||||
xst{m>2109:R,a>2952:A,a<2839:R,R}
|
||||
pr{a>3195:xxm,R}
|
||||
rnx{s<926:A,a>3544:R,A}
|
||||
ngl{a<2849:kzb,x>1007:R,vq}
|
||||
fhq{m<1694:R,m>3210:A,a>1513:A,A}
|
||||
ttd{x>952:R,m>216:R,m>132:R,A}
|
||||
tg{a>447:R,m<3009:R,s<3685:R,A}
|
||||
cgl{x>2271:A,s>3239:R,s<2541:cs,A}
|
||||
jh{a>3871:R,s<2611:A,R}
|
||||
vlx{m>2576:A,a<3152:R,m>1231:A,R}
|
||||
fh{s>1137:R,s<937:R,djf}
|
||||
xz{x<2419:sl,x<3456:rt,m>3040:fs,crn}
|
||||
pj{a<887:sq,s<3315:A,R}
|
||||
kjt{m<990:hqc,nkr}
|
||||
tb{m>1009:A,A}
|
||||
ppm{a<1310:R,a<1850:R,a<2261:R,R}
|
||||
jm{x<1054:R,a<579:R,A}
|
||||
fsf{x<3020:R,R}
|
||||
xxm{a<3299:R,R}
|
||||
pvh{s>929:A,R}
|
||||
bfx{a<3017:A,a>3351:gn,grz}
|
||||
fp{x<2966:tbv,x<3308:R,R}
|
||||
krr{x<677:tvn,A}
|
||||
vdz{m<3388:R,x<844:A,R}
|
||||
hzf{s>385:R,s<196:A,A}
|
||||
jjf{x>3217:A,m<616:qfn,dr}
|
||||
nq{x>2432:lg,m<1705:A,R}
|
||||
cmn{a<3539:rtg,a>3754:sf,dv}
|
||||
sq{a>365:R,m>2615:A,s>3324:A,A}
|
||||
xqf{x<554:A,m>1924:A,x>1244:A,R}
|
||||
gxc{a<350:A,s>506:fhg,vl}
|
||||
qx{a<3727:A,R}
|
||||
nzq{m<1027:R,s>1843:R,A}
|
||||
rv{a<3212:R,x>3734:R,m>3888:tq,tn}
|
||||
lrn{m>1353:kq,s<3039:jv,gx}
|
||||
nf{m>2662:A,x<3529:A,m>2179:A,R}
|
||||
zlz{a<750:mc,clh}
|
||||
kf{a>756:A,R}
|
||||
gj{m<1030:A,a>1937:R,R}
|
||||
gb{s<3174:A,s<3470:A,A}
|
||||
tnq{x>3001:A,R}
|
||||
zqv{m>691:A,R}
|
||||
kj{x<2954:psp,x>3147:mg,a>3127:mjb,A}
|
||||
tgn{a>1711:lkc,s>541:qt,R}
|
||||
npt{x<772:R,x>900:R,s<1084:R,A}
|
||||
cx{x>3400:lxp,lbv}
|
||||
vvt{s>278:R,A}
|
||||
vqq{x<3192:R,A}
|
||||
tq{s>2456:R,s<2301:R,x>3451:A,A}
|
||||
xxx{m<2342:R,A}
|
||||
dkr{a<2409:dg,m<1437:lvf,x>1274:gm,qdc}
|
||||
fs{s>1657:pbv,m<3482:A,m>3677:R,R}
|
||||
tpg{m<1159:A,x>3135:R,gmf}
|
||||
qln{a<2906:A,a>2928:R,a<2918:R,A}
|
||||
lvf{x<1270:bfx,x<1455:bzz,qk}
|
||||
xlq{m<334:A,s>1515:A,A}
|
||||
sx{m<1833:tfs,hf}
|
||||
gpt{a>2836:zxd,a>2730:R,A}
|
||||
krn{x>1155:ckd,s<1260:A,m>2770:A,zht}
|
||||
sk{m>348:R,x>1377:A,m>153:A,R}
|
||||
rl{a<984:R,R}
|
||||
ntd{a<819:dns,qnm}
|
||||
grz{x>890:A,a<3172:A,A}
|
||||
kt{x>967:A,R}
|
||||
qs{m<1546:A,R}
|
||||
js{x>3672:qmv,a>2929:hdn,hcs}
|
||||
bzz{m<647:sk,bg}
|
||||
vv{s>2934:sj,R}
|
||||
lbp{s>2775:R,R}
|
||||
zxd{x>1854:A,R}
|
||||
crn{s>1724:R,rn}
|
||||
jc{x>1851:R,s<3672:A,m<3477:A,R}
|
||||
xxh{m>1324:qqn,qm}
|
||||
pn{s<976:A,m<2297:R,A}
|
||||
fv{s>3818:A,s<3658:R,s<3743:R,A}
|
||||
ck{x>2824:R,m<316:R,A}
|
||||
vdp{x<3490:A,A}
|
||||
xq{m>184:A,x>3334:A,A}
|
||||
fz{m>3339:R,m>2690:R,x>2493:R,R}
|
||||
jf{m<1773:R,x>659:R,A}
|
||||
xd{a<3143:A,R}
|
||||
svq{a<3528:A,R}
|
||||
cl{x>3473:A,R}
|
||||
qf{x>3076:A,R}
|
||||
ktb{m<3197:A,s<704:R,s>1154:A,A}
|
||||
gbj{m<158:R,m<302:R,m>336:R,R}
|
||||
ff{s<2459:lmc,s>2743:R,nsj}
|
||||
rcn{s>3821:R,x>2847:A,a<2261:R,A}
|
||||
xkn{x>2134:R,x>1785:A,A}
|
||||
pf{a>3576:A,s>3815:A,s>3737:R,R}
|
||||
ntv{s<3659:R,A}
|
||||
psf{m>575:R,a<2611:A,m>319:R,R}
|
||||
fqz{a>3321:bx,vdp}
|
||||
tzp{x<554:ph,a>2615:lm,krn}
|
||||
pht{s>625:fh,x>606:ffn,sxb}
|
||||
zz{m<1836:ql,s>1299:hp,m<3200:shb,A}
|
||||
snl{s>3863:R,a<2001:xnj,kk}
|
||||
qdc{a<3128:ngl,a>3442:rnk,x<874:zm,gl}
|
||||
rsz{m>1017:R,x<2038:A,m<443:R,dzz}
|
||||
frj{m>1063:md,a>3826:rbn,s>1317:lb,zkk}
|
||||
bbt{a>3364:A,a<3152:R,R}
|
||||
lpg{x>3231:fqz,x<2909:nvk,s<2283:nm,lv}
|
||||
sd{s<1984:R,a>1624:A,m<729:A,A}
|
||||
spq{x<3000:A,s>148:A,R}
|
||||
fsv{s<2728:gj,m<1078:fpf,s>2917:R,R}
|
||||
rmq{s<3098:A,x<182:fg,cpn}
|
||||
msc{x>326:A,xxx}
|
||||
drg{a>1618:hzf,s>486:zjl,a>619:hzc,A}
|
||||
hx{x>3100:R,m<249:hnq,R}
|
||||
ksc{a>3214:A,x>2913:R,R}
|
||||
kxs{x<3497:R,s>949:A,A}
|
||||
xv{s>311:A,R}
|
||||
kd{x<3492:A,ppm}
|
||||
st{s<1839:R,m>810:R,pgj}
|
||||
ntb{m>3358:spq,m>2731:zhg,s<116:R,A}
|
||||
lqz{a>3814:A,A}
|
||||
fb{x>2177:tg,bjd}
|
||||
dcg{a<3359:pgb,rch}
|
||||
khp{a<2918:A,x>3796:R,m>378:R,A}
|
||||
hhs{x<3165:A,R}
|
||||
bnn{a<1158:R,x<228:A,A}
|
||||
nx{m>469:R,x>3876:R,x<3760:A,A}
|
||||
vl{m>1539:A,a>468:A,s>326:R,A}
|
||||
qmv{s<3328:R,A}
|
||||
rt{m<2818:fbx,R}
|
||||
hcs{x<3425:zsp,mk}
|
||||
mn{m<2363:A,R}
|
||||
sm{m<839:A,x>2835:A,s>1035:A,A}
|
||||
zn{x<2270:R,a>798:R,s>3678:R,A}
|
||||
qqn{m>1794:jt,a<3748:fdm,gkv}
|
||||
hdn{s>3198:A,s>3046:R,ngq}
|
||||
mg{x>3205:R,s<2688:R,A}
|
||||
sgc{x<3807:fhq,x<3919:A,bh}
|
||||
qhl{m>2988:A,x>3259:drn,xpv}
|
||||
zbr{x<2841:R,m>2724:R,R}
|
||||
rjb{x>2706:R,R}
|
||||
qp{m>1140:drg,tgn}
|
||||
kkk{s>1408:vzj,m<1501:dnp,s<833:dmc,dcf}
|
||||
cmr{a>3290:R,m>1084:R,m>506:R,A}
|
||||
lbv{m<3300:R,a<923:A,s<2435:bb,qq}
|
||||
mjb{m<3900:R,a>3686:A,R}
|
||||
clg{s>1434:nvh,m>3229:rsh,bt}
|
||||
hrn{a>3478:R,a>3380:R,m>1194:R,A}
|
||||
zhd{s>1275:R,m>3076:R,m<2721:A,R}
|
||||
hnq{x>2834:A,R}
|
||||
tbt{x>3131:A,m<3435:R,A}
|
||||
phc{a>3375:A,a<3306:R,A}
|
||||
vq{x<800:R,s>2917:R,x<922:R,R}
|
||||
kq{s<3392:sc,a>1260:hm,m>2319:fb,htk}
|
||||
fbx{a>3317:A,m<2345:A,R}
|
||||
cm{m<2219:R,m>2264:R,R}
|
||||
csz{s>3528:R,A}
|
||||
nst{x>2459:A,A}
|
||||
lf{a<3121:R,x<2716:R,m<818:R,A}
|
||||
xsp{x<2980:R,a>2817:A,A}
|
||||
qm{x<2949:kr,x<3428:jjf,s<456:jtt,jqn}
|
||||
qt{s<744:A,x<1059:R,s>816:R,A}
|
||||
zc{x>3545:qx,a>3625:vn,A}
|
||||
cxk{a>1449:ntt,s>1617:xbr,s>1504:R,xqf}
|
||||
cg{x>2245:zx,x<1956:zbk,vft}
|
||||
zkk{m<649:A,a>3680:R,R}
|
||||
bx{a<3661:A,x<3529:A,a>3778:R,R}
|
||||
mv{s>1300:rsc,khc}
|
||||
qjt{x<3376:A,R}
|
||||
mgp{x>3029:zq,A}
|
||||
fpf{a>1769:R,x>2049:A,s<2923:A,R}
|
||||
lhc{s>1662:A,m>1543:A,a<3599:tl,vfn}
|
||||
mzr{a<2819:R,R}
|
||||
psp{s<2611:A,a>3354:A,a>3056:A,A}
|
||||
vc{m<1333:cb,mp}
|
||||
bzc{m<1850:R,m<1953:A,R}
|
||||
kb{m<2614:mpn,m>3380:zhp,gqd}
|
||||
dv{a<3677:cfq,x<3383:R,s<2710:R,rq}
|
||||
xh{s<2524:A,R}
|
||||
vr{s>754:A,x<643:A,A}
|
||||
sj{s<3498:R,s<3711:R,m<1518:A,R}
|
||||
bq{a<1413:R,m>3189:A,a<1750:R,R}
|
||||
bgn{m<197:A,m<353:gbq,xh}
|
||||
jl{x>2858:R,m<476:R,R}
|
||||
vbr{x<2055:R,m>2096:A,R}
|
||||
ngq{a>3426:R,s<3009:A,a<3210:A,R}
|
||||
krj{x>2852:pjd,gf}
|
||||
dp{m>1430:A,A}
|
||||
xkm{m<1913:kjv,vz}
|
||||
vg{x>224:R,a>1513:A,m<323:A,R}
|
||||
jmf{s<1182:A,a>3547:A,A}
|
||||
vqr{a>3441:ljt,A}
|
||||
ckd{m>3131:R,a<1567:R,m>2271:R,A}
|
||||
bp{s>3270:A,s>3133:R,R}
|
||||
pc{x>3663:A,m<491:R,A}
|
||||
mx{m>663:bs,m<622:tjb,gkn}
|
||||
qhh{x<1947:A,m>3589:A,R}
|
||||
ths{a>2010:dp,R}
|
||||
znh{m>662:A,x>2990:R,R}
|
||||
fph{a>2941:R,s<1649:R,R}
|
||||
nkr{x<1012:npt,m>1326:A,s>1224:R,R}
|
||||
zbc{x>2881:R,x>2784:rcn,x>2722:xf,rjb}
|
||||
hp{s>1600:R,s>1465:R,a>263:R,R}
|
||||
kdf{s>420:R,m>1639:R,x>2176:A,R}
|
||||
hkl{s<3823:bn,m>3668:sp,s>3936:A,A}
|
||||
lp{m>3026:tbt,s>1876:R,bj}
|
||||
zmt{a>3930:fn,a<3915:bcz,ktb}
|
||||
jqn{a<3862:pc,m<761:R,a<3938:ldl,A}
|
||||
hms{x>3072:A,s<1921:R,A}
|
||||
sn{s>774:A,s>753:R,x>547:A,A}
|
||||
kx{m>1998:tbn,A}
|
||||
mqc{m<2308:A,m>3052:A,m>2635:R,A}
|
||||
qdj{a>2946:zgm,a<2669:fqc,m>2271:lzv,ndr}
|
||||
xt{a>3826:A,x<3063:A,A}
|
||||
kvr{m>1390:R,x>3294:A,R}
|
||||
hz{x>2278:A,x<1949:A,A}
|
||||
fkj{x<3168:A,s<2741:R,R}
|
||||
tn{m<3831:R,s>2560:R,A}
|
||||
zjl{s>694:R,R}
|
||||
ndr{a<2827:cgl,x<2240:rsz,xn}
|
||||
btj{m<1813:qs,m<2042:jg,cm}
|
||||
bjd{x<1891:A,s>3600:A,A}
|
||||
gjg{m>2075:rjd,a<3588:fx,s<809:xxh,rss}
|
||||
zch{s<3538:hl,m<2003:zlz,dz}
|
||||
nrf{s>428:vkl,s>146:qsg,a>957:pmd,dxn}
|
||||
vhc{s>1085:tpg,jxf}
|
||||
lb{m<643:xlq,a>3717:svn,m>911:dsr,ds}
|
||||
zdc{x>1803:R,A}
|
||||
bzj{s>3689:A,m<2560:R,R}
|
||||
flt{s>1360:A,x>2163:A,A}
|
||||
qg{s>1039:A,A}
|
||||
dm{m<3816:A,s<3853:R,A}
|
||||
xmg{m>752:A,x>137:jzj,gsl}
|
||||
bcz{a<3903:R,R}
|
||||
lkc{a>3188:A,m<900:A,m>1018:A,R}
|
||||
jxf{s<527:srg,A}
|
||||
gx{m>486:dq,ntd}
|
||||
bd{s>2400:A,x>3671:A,s>2281:R,A}
|
||||
qc{s<2673:R,A}
|
||||
lm{a<3182:dj,a>3635:lqz,a>3407:R,R}
|
||||
qnm{m<247:R,a>1687:R,m>389:A,A}
|
||||
zq{s>3263:R,s>3111:R,R}
|
||||
mk{s>3246:A,m>2016:R,s<3088:A,R}
|
||||
rql{a<3077:xsp,s>2761:jl,s>2722:R,A}
|
||||
vj{s<2785:ndh,kd}
|
||||
in{s>2178:zs,skv}
|
||||
xrc{s>712:sn,A}
|
||||
jp{a<2589:R,A}
|
||||
pgj{a>3929:R,x>2479:A,A}
|
||||
jts{x>3530:R,A}
|
||||
gv{s>3739:A,R}
|
||||
mnr{s>2737:R,A}
|
||||
tgt{m>1439:R,s>292:R,A}
|
||||
xvs{a<2848:A,A}
|
||||
vps{a>3227:A,x<1588:R,A}
|
||||
jzj{m<672:A,s<1122:R,R}
|
||||
zzp{x<901:ch,R}
|
||||
sl{s>1542:A,s>1296:R,x>1931:A,zxz}
|
||||
rjd{a>3500:xzq,s<1086:qj,xz}
|
||||
kgd{s>1426:A,a>3812:A,R}
|
||||
dmc{m<2947:szv,kqx}
|
||||
hbk{m<3419:A,R}
|
||||
htk{a<729:R,a>1042:A,a>861:R,zn}
|
||||
zp{s<1255:A,A}
|
||||
qlx{m>1631:R,x>3329:R,R}
|
||||
skv{x<1606:kkk,a<1440:ggv,a<3018:xkm,gjg}
|
||||
zl{m>3149:A,a>3596:A,R}
|
||||
sjc{m>2149:A,A}
|
||||
ggv{x>2600:nh,cg}
|
||||
pd{a<3356:pr,x<2700:xfj,a<3465:zbd,xv}
|
||||
vhk{a<614:A,a>735:A,m>3340:A,R}
|
||||
bz{x<2317:R,s<3304:A,A}
|
||||
zbd{m>889:zfk,bdh}
|
||||
vsj{a<598:zhd,R}
|
||||
qzf{a>1455:R,x>340:A,s<1196:R,R}
|
||||
dz{m<3157:qv,x>3473:hkl,a>877:sv,rf}
|
||||
rtg{a>2957:R,A}
|
||||
qk{a>3252:svq,s>3213:R,m>548:cfz,R}
|
||||
zx{a>871:sxt,a>314:mn,a>186:zz,nq}
|
||||
kcd{x<2880:R,s>94:R,R}
|
||||
hqc{m<796:R,m>890:rhd,a<2192:A,xvs}
|
||||
ffn{m>350:jp,a<2088:ttd,a>2817:R,R}
|
||||
sz{m<1599:R,x>2121:ktx,m<3075:bbt,qhh}
|
||||
jtt{a<3836:zqv,m<876:gg,A}
|
||||
lmr{a<2718:A,a<3149:R,R}
|
||||
zdv{s>3010:R,lr}
|
||||
jcl{m<1659:A,R}
|
||||
mdq{a<479:R,A}
|
||||
dnp{m<537:pht,s<885:qp,x<582:bjg,kjt}
|
||||
lxp{m>2932:A,lx}
|
||||
kqx{s<513:hbk,a<1592:ncn,a>3119:xrc,kt}
|
||||
cnl{x<1035:R,m<2338:A,R}
|
||||
mp{m<2347:xpj,a>2221:vdz,bq}
|
||||
rgx{s<2542:R,R}
|
||||
rb{s<3903:A,A}
|
||||
jk{m>2376:R,x>3391:R,m<1198:R,R}
|
||||
zgm{s>3092:bzj,sz}
|
||||
gt{a>1014:R,m<2365:ls,R}
|
||||
jpn{s>1819:hj,a>3326:vqr,ljm}
|
||||
nzj{s>254:R,m>2156:R,x<991:jf,qhq}
|
||||
gh{m>856:A,nsp}
|
||||
kpq{a<110:A,x>3312:R,x<3090:R,R}
|
||||
hl{x<3177:pj,bp}
|
||||
gs{a<180:R,s>3703:R,R}
|
||||
gz{m>3188:R,R}
|
||||
lft{s>2829:ps,gbj}
|
||||
kzb{m>2754:A,a<2674:A,A}
|
||||
vz{a>2453:pp,clg}
|
||||
tqc{x<360:dk,zcq}
|
||||
bxv{a<2317:A,m<2884:pn,fkp}
|
||||
ztl{a<590:R,x<2295:R,x>2529:R,R}
|
||||
vkk{a>3382:zc,x>3140:xrl,m<384:lft,rql}
|
||||
fbv{s<3805:R,s>3881:R,a>172:R,R}
|
||||
gbq{m>279:A,x<3717:R,x<3898:A,R}
|
||||
svn{s<1485:R,A}
|
||||
skb{s>589:R,s>295:R,x>2063:A,A}
|
||||
mc{a>272:A,x>3488:gs,s>3786:A,fsf}
|
||||
pbv{x<3811:R,a>3290:A,m<3444:R,A}
|
||||
gkn{s<1377:A,A}
|
||||
nth{a<1084:bd,A}
|
||||
vsl{a<2799:A,a<2901:bgb,fph}
|
||||
lr{x<1407:A,s>2654:R,s<2373:A,R}
|
||||
dbq{m<1824:R,s>291:R,A}
|
||||
hdt{s>3011:R,s>2681:A,bgg}
|
||||
nvq{m>597:R,x>47:R,A}
|
||||
qj{s>674:pz,s>313:srn,ntb}
|
||||
fgp{a>3257:R,mcl}
|
||||
pjd{s<3848:vlx,A}
|
||||
gmf{s<1729:A,A}
|
||||
kzp{x>1746:A,x>1670:A,m>2460:A,A}
|
||||
tl{m<888:A,m<1289:A,R}
|
||||
zh{m<1334:fzz,s>2674:vj,m<2347:cdt,cx}
|
||||
ql{s<1432:A,a>258:R,A}
|
||||
rch{s<485:R,vqq}
|
||||
hf{a<3208:R,pf}
|
||||
bj{x<2870:R,m<2489:A,R}
|
||||
zhg{x>3190:A,s>144:R,m<2941:A,R}
|
||||
rsh{x<3060:R,a<1833:pm,R}
|
||||
ntt{a>1930:R,a<1611:A,A}
|
||||
hd{s>1811:A,R}
|
||||
dfd{x<2726:A,qg}
|
||||
gqd{a>3471:qjt,qhl}
|
||||
xrl{x>3598:khp,m>284:lbp,m<100:R,xq}
|
||||
zxz{m<2818:A,R}
|
||||
vfn{s>1502:R,x>955:R,s>1440:A,R}
|
||||
dr{s<370:A,x>3070:R,R}
|
||||
cth{a<2210:cxk,a>3174:lhc,krr}
|
||||
xbr{m<1775:R,m>3200:A,A}
|
||||
nn{m>718:R,x>3641:nx,A}
|
||||
dxn{s<55:hr,x>3309:A,a<824:kcd,mqc}
|
||||
mt{a<423:R,a>555:R,R}
|
||||
hqk{a>2663:A,s<888:R,a<2564:R,A}
|
||||
ns{a<2307:lrn,qdj}
|
||||
sxb{s>318:vg,hgv}
|
||||
ljm{s<1457:A,m>763:A,s>1648:R,A}
|
||||
qcr{s<1460:R,m<548:hms,a>1054:A,nzq}
|
||||
sxx{a>3455:A,R}
|
||||
|
||||
{x=378,m=450,a=211,s=36}
|
||||
{x=220,m=1090,a=338,s=879}
|
||||
{x=117,m=124,a=2136,s=128}
|
||||
{x=1392,m=1408,a=126,s=16}
|
||||
{x=2038,m=278,a=901,s=1801}
|
||||
{x=323,m=1703,a=964,s=571}
|
||||
{x=265,m=358,a=456,s=34}
|
||||
{x=1513,m=144,a=525,s=1341}
|
||||
{x=355,m=2036,a=814,s=1179}
|
||||
{x=937,m=701,a=2026,s=1349}
|
||||
{x=1292,m=766,a=2805,s=16}
|
||||
{x=319,m=26,a=83,s=1193}
|
||||
{x=600,m=5,a=242,s=76}
|
||||
{x=117,m=1415,a=1636,s=1057}
|
||||
{x=87,m=1530,a=1686,s=386}
|
||||
{x=36,m=957,a=1712,s=300}
|
||||
{x=2570,m=49,a=661,s=442}
|
||||
{x=643,m=698,a=1593,s=854}
|
||||
{x=1450,m=1410,a=289,s=1342}
|
||||
{x=1690,m=376,a=584,s=3715}
|
||||
{x=1942,m=570,a=1726,s=1192}
|
||||
{x=420,m=475,a=1410,s=863}
|
||||
{x=550,m=662,a=2140,s=105}
|
||||
{x=241,m=2370,a=756,s=26}
|
||||
{x=705,m=425,a=1000,s=160}
|
||||
{x=1763,m=914,a=197,s=555}
|
||||
{x=2267,m=323,a=70,s=147}
|
||||
{x=497,m=392,a=1959,s=360}
|
||||
{x=428,m=1375,a=415,s=236}
|
||||
{x=1800,m=96,a=403,s=1227}
|
||||
{x=216,m=381,a=1217,s=1031}
|
||||
{x=3129,m=304,a=811,s=1753}
|
||||
{x=555,m=59,a=3254,s=2896}
|
||||
{x=397,m=1518,a=740,s=496}
|
||||
{x=905,m=217,a=1234,s=2319}
|
||||
{x=283,m=2490,a=309,s=1156}
|
||||
{x=1777,m=624,a=96,s=2053}
|
||||
{x=1031,m=481,a=1014,s=198}
|
||||
{x=155,m=205,a=2460,s=832}
|
||||
{x=123,m=25,a=3962,s=3662}
|
||||
{x=3242,m=396,a=519,s=150}
|
||||
{x=2632,m=1307,a=3594,s=1714}
|
||||
{x=147,m=285,a=1020,s=40}
|
||||
{x=1498,m=1133,a=241,s=1263}
|
||||
{x=1977,m=323,a=1594,s=241}
|
||||
{x=807,m=1042,a=702,s=295}
|
||||
{x=70,m=455,a=1328,s=108}
|
||||
{x=2392,m=27,a=158,s=44}
|
||||
{x=528,m=671,a=2003,s=935}
|
||||
{x=1539,m=2002,a=168,s=479}
|
||||
{x=2121,m=195,a=901,s=1116}
|
||||
{x=251,m=51,a=380,s=745}
|
||||
{x=793,m=1959,a=598,s=605}
|
||||
{x=137,m=261,a=714,s=1548}
|
||||
{x=2783,m=486,a=2065,s=914}
|
||||
{x=574,m=387,a=250,s=28}
|
||||
{x=3,m=829,a=1862,s=2}
|
||||
{x=846,m=2476,a=841,s=1810}
|
||||
{x=1020,m=114,a=463,s=323}
|
||||
{x=4,m=970,a=192,s=142}
|
||||
{x=942,m=2297,a=125,s=1638}
|
||||
{x=1664,m=2275,a=2086,s=290}
|
||||
{x=682,m=93,a=143,s=2033}
|
||||
{x=1613,m=356,a=463,s=632}
|
||||
{x=633,m=268,a=150,s=798}
|
||||
{x=1743,m=1455,a=56,s=487}
|
||||
{x=2774,m=103,a=739,s=77}
|
||||
{x=1760,m=2631,a=81,s=138}
|
||||
{x=461,m=1688,a=1543,s=1712}
|
||||
{x=1182,m=14,a=566,s=3270}
|
||||
{x=680,m=467,a=1920,s=297}
|
||||
{x=1281,m=2355,a=704,s=1340}
|
||||
{x=142,m=65,a=589,s=20}
|
||||
{x=1412,m=559,a=677,s=2106}
|
||||
{x=905,m=2761,a=1526,s=648}
|
||||
{x=399,m=667,a=1901,s=27}
|
||||
{x=2241,m=3411,a=1786,s=321}
|
||||
{x=1395,m=1278,a=508,s=1112}
|
||||
{x=363,m=35,a=218,s=1280}
|
||||
{x=829,m=115,a=304,s=192}
|
||||
{x=1397,m=599,a=861,s=838}
|
||||
{x=824,m=2140,a=88,s=1736}
|
||||
{x=661,m=276,a=502,s=731}
|
||||
{x=585,m=14,a=705,s=473}
|
||||
{x=747,m=95,a=829,s=805}
|
||||
{x=2006,m=323,a=982,s=168}
|
||||
{x=795,m=193,a=473,s=1531}
|
||||
{x=687,m=428,a=972,s=1154}
|
||||
{x=254,m=426,a=281,s=552}
|
||||
{x=171,m=369,a=382,s=1369}
|
||||
{x=964,m=10,a=322,s=2007}
|
||||
{x=1960,m=183,a=2153,s=1967}
|
||||
{x=2315,m=170,a=41,s=727}
|
||||
{x=189,m=901,a=307,s=3026}
|
||||
{x=757,m=1235,a=1316,s=335}
|
||||
{x=836,m=3023,a=453,s=2355}
|
||||
{x=2187,m=2140,a=683,s=2560}
|
||||
{x=1772,m=468,a=1812,s=1329}
|
||||
{x=783,m=601,a=1339,s=3291}
|
||||
{x=570,m=172,a=1794,s=120}
|
||||
{x=1207,m=1572,a=700,s=758}
|
||||
{x=1961,m=3652,a=702,s=153}
|
||||
{x=1094,m=435,a=19,s=938}
|
||||
{x=3328,m=166,a=247,s=216}
|
||||
{x=1500,m=2012,a=1561,s=59}
|
||||
{x=12,m=2269,a=8,s=796}
|
||||
{x=193,m=1137,a=328,s=13}
|
||||
{x=120,m=1179,a=59,s=1829}
|
||||
{x=499,m=650,a=1049,s=1803}
|
||||
{x=2761,m=1431,a=389,s=1322}
|
||||
{x=456,m=2766,a=2165,s=348}
|
||||
{x=2387,m=12,a=2140,s=556}
|
||||
{x=387,m=7,a=1514,s=1137}
|
||||
{x=1111,m=608,a=581,s=965}
|
||||
{x=1055,m=181,a=754,s=67}
|
||||
{x=74,m=2582,a=66,s=546}
|
||||
{x=5,m=956,a=1013,s=657}
|
||||
{x=262,m=189,a=2496,s=233}
|
||||
{x=518,m=2821,a=851,s=825}
|
||||
{x=351,m=1981,a=221,s=34}
|
||||
{x=995,m=165,a=36,s=2286}
|
||||
{x=1636,m=335,a=936,s=447}
|
||||
{x=763,m=692,a=1527,s=210}
|
||||
{x=301,m=559,a=1815,s=2640}
|
||||
{x=959,m=2852,a=232,s=53}
|
||||
{x=136,m=153,a=206,s=11}
|
||||
{x=1533,m=42,a=2014,s=136}
|
||||
{x=341,m=378,a=37,s=577}
|
||||
{x=220,m=1451,a=185,s=421}
|
||||
{x=1086,m=3265,a=1184,s=2960}
|
||||
{x=143,m=2701,a=602,s=173}
|
||||
{x=628,m=1016,a=1642,s=223}
|
||||
{x=597,m=641,a=1331,s=651}
|
||||
{x=809,m=1843,a=1111,s=2189}
|
||||
{x=1385,m=1352,a=238,s=1969}
|
||||
{x=515,m=1374,a=125,s=913}
|
||||
{x=798,m=2743,a=1798,s=1045}
|
||||
{x=2999,m=1787,a=1168,s=188}
|
||||
{x=57,m=77,a=2652,s=56}
|
||||
{x=1231,m=304,a=1288,s=523}
|
||||
{x=1031,m=381,a=558,s=267}
|
||||
{x=721,m=883,a=2995,s=22}
|
||||
{x=304,m=846,a=1525,s=30}
|
||||
{x=446,m=2969,a=412,s=674}
|
||||
{x=187,m=418,a=1187,s=571}
|
||||
{x=810,m=515,a=819,s=1393}
|
||||
{x=740,m=3392,a=1128,s=1114}
|
||||
{x=137,m=631,a=1208,s=1707}
|
||||
{x=653,m=2468,a=952,s=811}
|
||||
{x=33,m=70,a=518,s=464}
|
||||
{x=3318,m=2,a=3661,s=64}
|
||||
{x=50,m=548,a=1657,s=704}
|
||||
{x=2272,m=2684,a=1597,s=2220}
|
||||
{x=185,m=339,a=460,s=517}
|
||||
{x=8,m=1651,a=1810,s=354}
|
||||
{x=548,m=833,a=1703,s=759}
|
||||
{x=551,m=358,a=390,s=468}
|
||||
{x=202,m=2260,a=597,s=632}
|
||||
{x=453,m=1811,a=754,s=2449}
|
||||
{x=353,m=101,a=1835,s=72}
|
||||
{x=1451,m=453,a=162,s=13}
|
||||
{x=125,m=2120,a=627,s=981}
|
||||
{x=5,m=283,a=1755,s=194}
|
||||
{x=973,m=835,a=62,s=1184}
|
||||
{x=346,m=1348,a=442,s=210}
|
||||
{x=4,m=1242,a=136,s=196}
|
||||
{x=2388,m=1336,a=1991,s=2873}
|
||||
{x=561,m=2335,a=1059,s=627}
|
||||
{x=838,m=3226,a=159,s=1053}
|
||||
{x=2578,m=49,a=1920,s=2432}
|
||||
{x=710,m=342,a=182,s=534}
|
||||
{x=1997,m=1509,a=946,s=1849}
|
||||
{x=810,m=249,a=495,s=257}
|
||||
{x=363,m=274,a=2742,s=25}
|
||||
{x=506,m=565,a=2584,s=731}
|
||||
{x=508,m=2073,a=21,s=1826}
|
||||
{x=1413,m=780,a=779,s=378}
|
||||
{x=1097,m=47,a=98,s=402}
|
||||
{x=536,m=2,a=2710,s=1499}
|
||||
{x=548,m=2845,a=2095,s=555}
|
||||
{x=2963,m=2206,a=1920,s=875}
|
||||
{x=1783,m=367,a=1245,s=594}
|
||||
{x=409,m=18,a=408,s=119}
|
||||
{x=1554,m=3613,a=3002,s=87}
|
||||
{x=232,m=197,a=63,s=1372}
|
||||
{x=412,m=1355,a=1673,s=1667}
|
||||
{x=261,m=142,a=123,s=1187}
|
||||
{x=1396,m=779,a=287,s=60}
|
||||
{x=28,m=1350,a=585,s=861}
|
||||
{x=1123,m=329,a=1166,s=62}
|
||||
{x=2292,m=73,a=123,s=596}
|
||||
{x=2400,m=1430,a=390,s=1313}
|
||||
{x=638,m=2856,a=44,s=488}
|
||||
{x=294,m=1534,a=1075,s=1914}
|
||||
{x=1233,m=71,a=253,s=3058}
|
||||
{x=1536,m=805,a=158,s=738}
|
||||
{x=2903,m=119,a=2344,s=2387}
|
||||
{x=142,m=1768,a=940,s=881}
|
||||
{x=301,m=2748,a=739,s=766}
|
||||
{x=127,m=18,a=141,s=1398}
|
||||
255
day19/main.go
Normal file
255
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}
|
||||
}
|
||||
41
day19/main_test.go
Normal file
41
day19/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, 19114)
|
||||
is.Equal(result.valuePT2, uint(167409079868000))
|
||||
}
|
||||
|
||||
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, 377025)
|
||||
is.Equal(result.valuePT2, uint(135506683246673))
|
||||
}
|
||||
5
day20/example1.txt
Normal file
5
day20/example1.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
broadcaster -> a, b, c
|
||||
%a -> b
|
||||
%b -> c
|
||||
%c -> inv
|
||||
&inv -> a
|
||||
5
day20/example2.txt
Normal file
5
day20/example2.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
broadcaster -> a
|
||||
%a -> inv, con
|
||||
&inv -> b
|
||||
%b -> con
|
||||
&con -> output
|
||||
58
day20/input.txt
Normal file
58
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
day20/main.go
Normal file
282
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
day20/main_test.go
Normal file
56
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)
|
||||
}
|
||||
23
day23/example.txt
Normal file
23
day23/example.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
#.#####################
|
||||
#.......#########...###
|
||||
#######.#########.#.###
|
||||
###.....#.>.>.###.#.###
|
||||
###v#####.#v#.###.#.###
|
||||
###.>...#.#.#.....#...#
|
||||
###v###.#.#.#########.#
|
||||
###...#.#.#.......#...#
|
||||
#####.#.#.#######.#.###
|
||||
#.....#.#.#.......#...#
|
||||
#.#####.#.#.#########v#
|
||||
#.#...#...#...###...>.#
|
||||
#.#.#v#######v###.###v#
|
||||
#...#.>.#...>.>.#.###.#
|
||||
#####v#.#.###v#.#.###.#
|
||||
#.....#...#...#.#.#...#
|
||||
#.#########.###.#.#.###
|
||||
#...###...#...#...#.###
|
||||
###.###.#.###v#####v###
|
||||
#...#...#.#.>.>.#.>.###
|
||||
#.###.###.#.###.#.#v###
|
||||
#.....###...###...#...#
|
||||
#####################.#
|
||||
141
day23/input.txt
Normal file
141
day23/input.txt
Normal file
@@ -0,0 +1,141 @@
|
||||
#.###########################################################################################################################################
|
||||
#.#...#.......#...#.....#...#...#######...###...#...#.......#...#...#...#...#...#...#...###...###...###...............#.....#...#######...###
|
||||
#.#.#.#.#####.#.#.#.###.#.#.#.#.#######.#.###.#.#.#.#.#####.#.#.#.#.#.#.#.#.#.#.#.#.#.#.###.#.###.#.###.#############.#.###.#.#.#######.#.###
|
||||
#.#.#.#.#.....#.#.#...#.#.#...#...#.....#...#.#.#.#.#.....#...#.#.#.#.#.#.#.#.#...#...#.....#.#...#...#.............#.#...#...#.......#.#...#
|
||||
#.#.#.#.#.#####.#.###.#.#.#######.#.#######.#.#.#.#.#####.#####.#.#.#.#.#.#.#.###############.#.#####.#############.#.###.###########.#.###.#
|
||||
#...#...#.....#.#.###.#.#.#.......#.....#...#.#.#.#.#.>.>.#.....#.#.#.#.#.#.#...#.............#.#.....#...#.......#.#.....#...........#.#...#
|
||||
#############.#.#v###.#.#.#.###########.#.###.#.#.#.#.#v###.#####.#.#.#.#.#.###.#.#############.#.#####.#.#.#####.#.#######.###########.#.###
|
||||
#...###...###...#.>.#.#.#.#.#...###.....#.....#.#.#...#...#.#...#.#.#.#.#.#.###.#.#####...###...#...#...#.#...#...#.....#...#...###...#.#.###
|
||||
#.#.###.#.#######v#.#.#.#.#.#.#.###.###########.#.#######.#.#.#.#.#.#.#.#.#.###.#.#####.#.###.#####.#.###.###.#.#######.#.###.#.###.#.#.#.###
|
||||
#.#.#...#.#.....#.#.#.#.#.#...#...#.........#...#.###.....#.#.#.#.#.#.#.#.#.>.>.#.......#.#...#.....#...#.#...#.#.......#...#.#.....#.#.#.###
|
||||
#.#.#.###.#.###.#.#.#.#.#.#######.#########.#.###.###.#####.#.#.#.#.#.#.#.###v###########.#.###.#######.#.#.###.#.#########.#.#######.#.#.###
|
||||
#.#.#...#.#...#.#.#.#.#.#...#.....#...#...#.#...#...#.....#.#.#.#.#.#.#...###.#...........#...#.....#...#.#...#.#.........#.#.#.......#.#.###
|
||||
#.#.###.#.###.#.#.#.#.#.###.#.#####.#.#.#.#.###.###.#####.#.#.#.#.#.#.#######.#.#############.#####.#.###.###.#.#########.#.#.#.#######.#.###
|
||||
#.#.....#.#...#.#.#.#.#.#...#.....#.#...#.#...#.#...#.....#...#...#.#.#.......#.#.....#.....#.#.....#...#.###.#.#...#.....#...#.#...###.#.###
|
||||
#.#######.#.###.#.#.#.#.#.#######.#.#####.###.#.#.###.#############.#.#.#######.#.###.#.###.#.#.#######.#.###.#.#.#.#.#########.#.#.###.#.###
|
||||
#.#...###...###.#.#...#.#...#.....#.#...#...#.#.#...#...........###...#.......#.#.#...#...#.#.#.#...###.#.###.#.#.#.#.....#.....#.#.#...#...#
|
||||
#.#.#.#########.#.#####.###.#.#####.#.#.###.#.#.###.###########.#############.#.#.#.#####.#.#.#.#.#.###.#.###.#.#.#.#####.#.#####.#.#.#####.#
|
||||
#.#.#.........#...#.....#...#.#...#...#...#...#.....#####.......#...###.......#.#.#.#.....#.#.#.#.#.#...#.>.>.#.#.#.#.....#...#...#...###...#
|
||||
#.#.#########.#####.#####.###.#.#.#######.###############.#######.#.###.#######.#.#.#.#####.#.#.#.#.#.#####v###.#.#.#.#######.#.#########.###
|
||||
#...#.......#.#...#...#...###.#.#.>.>...#...#...#...###...###...#.#...#.......#.#.#...###...#.#.#.#.#...#...###...#...###.....#.###.......###
|
||||
#####.#####.#.#.#.###.#.#####.#.###v###.###.#.#.#.#.###.#####.#.#.###.#######.#.#.#######.###.#.#.#.###.#.###############.#####.###.#########
|
||||
#...#.....#...#.#.###...#####...#...###.....#.#.#.#.#...#...#.#...#...#.......#.#.#.....#.....#.#.#.....#...#...........#.#...#...#...#.....#
|
||||
#.#.#####.#####.#.###############.###########.#.#.#.#.###.#.#.#####.###.#######.#.#.###.#######.#.#########.#.#########.#.#.#.###.###.#.###.#
|
||||
#.#.......#...#.#.#...#...###...#.....#.......#.#.#...#...#...#.....###.......#...#...#.#.....#.#...#...###...#.........#...#.#...###...#...#
|
||||
#.#########.#.#.#.#.#.#.#.###.#.#####.#.#######.#.#####.#######.#############.#######.#.#.###.#.###.#.#.#######.#############.#.#########.###
|
||||
#.........#.#.#.#.#.#.#.#...#.#.......#.#.......#.......###.....#...#.........###...#.#.#.#...#.....#.#.#...###.............#...#...#...#...#
|
||||
#########.#.#.#.#.#.#.#.###.#.#########.#.#################.#####.#.#.###########.#.#.#.#.#.#########.#.#.#.###############.#####.#.#.#.###.#
|
||||
#.........#.#.#.#.#.#.#...#.#.......###.#.#...#...#...#...#.....#.#.#.......#...#.#...#.#.#...#.......#.#.#...#.............#...#.#...#.....#
|
||||
#.#########.#.#.#.#.#.###.#.#######v###.#.#.#.#.#.#.#.#.#.#####v#.#.#######.#.#.#.#####.#.###.#.#######.#.###.#.#############.#.#.###########
|
||||
#...........#.#.#...#.#...#...#...>.>.#.#...#.#.#...#.#.#...#.>.>.#.#...###.#.#.#.....#.#.#...#.......#.#...#.#...#...#...###.#.#...........#
|
||||
#############.#.#####.#.#####.#.###v#.#.#####.#.#####.#.###.#.#v###.#.#.###v#.#.#####.#.#.#.#########.#.###.#.###v#.#.#.#.###.#.###########.#
|
||||
#...#...#.....#.....#.#.#.....#.#...#.#.....#.#...###...#...#.#...#.#.#.#.>.>.#.#...#.#.#.#...#.......#...#.#.#.>.>.#...#...#.#...#.........#
|
||||
#.#.#.#.#.#########.#.#.#.#####.#.###.#####.#.###.#######.###.###.#.#.#.#.#v###.#.#.#.#.#.###.#.#########.#.#.#.#v#########.#.###.#.#########
|
||||
#.#...#.#.#####...#.#.#.#.#.....#...#...#...#.#...#.....#...#...#.#...#...#.###...#...#...#...#.......###...#...#.#...#...#.#.#...#...#...###
|
||||
#.#####.#.#####.#.#.#.#.#.#.#######.###.#.###.#.###.###.###.###.#.#########.###############.#########.###########.#.#.#.#.#.#.#.#####.#.#.###
|
||||
#.....#...###...#.#.#...#...#.....#...#.#.#...#.....#...###.....#.....#.....#...#...#...###...#.......#...#...###.#.#...#...#.#...###...#...#
|
||||
#####.#######.###.#.#########.###.###.#.#.#.#########.###############.#.#####.#.#.#.#.#.#####.#.#######.#.#.#.###.#.#########.###.#########.#
|
||||
#.....#...#...###...#...#.....###...#.#.#.#.#...#...#...#.............#...#...#...#...#.....#.#.....#...#...#...#.#.###...###...#.#...#.....#
|
||||
#.#####.#.#.#########.#.#.#########.#.#.#.#.#.#.#.#.###.#.###############.#.###############.#.#####.#.#########.#.#.###.#.#####.#.#.#.#.#####
|
||||
#.....#.#...#####.....#.#.........#...#.#.#.#.#...#.#...#...............#...#...............#.#.....#.#.....#...#.#.#...#.#...#.#.#.#.#...###
|
||||
#####.#.#########.#####.#########.#####.#.#.#.#####.#.#################.#####.###############.#.#####.#.###.#.###.#.#.###.#.#.#.#.#.#.###v###
|
||||
#...#.#.........#.#...#...........#...#...#.#.....#.#.#.................#.....#.....#.......#.#.....#...#...#.....#.#.###.#.#.#.#.#.#.#.>.###
|
||||
#.#.#v#########.#.#.#.#############.#.#####.#####.#.#.#.#################.#####.###.#.#####.#.#####.#####.#########.#.###.#.#.#.#.#.#.#.#v###
|
||||
#.#.#.>...#.....#...#...............#.....#.#...#.#...#.#...#...........#.#.....###...#.....#.......#...#.........#.#...#.#.#...#.#.#...#...#
|
||||
#.#.#v###.#.#############################.#.#.#.#.#####.#.#.#.#########.#.#.###########.#############.#.#########.#.###.#.#.#####.#.#######.#
|
||||
#.#.#...#.#.......#.......................#...#...#...#...#...#...#.....#.#.#...........#...#...###...#...........#.#...#.#.#.....#.#.......#
|
||||
#.#.###.#.#######.#.###############################.#.#########.#.#.#####.#.#.###########.#.#.#.###.###############.#.###.#.#.#####.#.#######
|
||||
#.#.....#.........#...#...#.........###...#...#...#.#.#.........#...#...#...#.#...........#.#.#...#.........#.....#...###.#.#.#.....#.#.....#
|
||||
#.###################.#.#.#.#######.###.#.#.#.#.#.#.#.#.#############.#.#####.#.###########.#.###.#########.#.###.#######.#.#.#.#####.#.###.#
|
||||
#...#...###.....#...#...#.#.#.......#...#...#.#.#.#.#.#.............#.#.....#...#...........#.#...#.........#...#.....###...#...#...#...#...#
|
||||
###.#.#.###.###.#.#.#####.#.#.#######.#######.#.#.#.#.#############.#.#####.#####.###########.#.###.###########.#####.###########.#.#####.###
|
||||
#...#.#...#...#.#.#.#.....#.#.....###.#.......#.#...#...#...#...###...#.....#...#.......#...#.#.###.......###...#.....#...#.....#.#...###...#
|
||||
#.###.###.###.#.#.#.#.#####.#####.###.#.#######.#######.#.#.#.#.#######.#####.#.#######.#.#.#.#.#########v###.###.#####.#.#.###.#.###.#####.#
|
||||
#.....###.....#.#.#.#.......#...#...#.#.....###.......#.#.#...#.#.......#####.#.........#.#.#.#...#.....>.>.#...#.#...#.#.#.#...#...#.###...#
|
||||
###############.#.#.#########.#.###.#.#####.#########.#.#.#####.#.###########.###########.#.#.###.#.#####v#.###.#.#.#.#.#.#.#.#####.#.###v###
|
||||
#...............#.#.#.......#.#.....#.#.....#...#...#.#.#.....#.#...........#...#...#...#.#.#.#...#.....#.#.....#.#.#.#.#.#.#...#...#...>.###
|
||||
#.###############.#.#.#####.#.#######.#.#####.#.#.#.#.#.#####.#.###########.###.#.#.#.#.#.#.#.#.#######.#.#######.#.#.#.#.#.###.#.#######v###
|
||||
#...#.....#...###.#.#.....#.#.#...###.#.#...#.#.#.#.#.#.#...#.#.###.........###...#...#.#.#...#...#.....#.....#...#.#...#.#...#.#.#.....#.###
|
||||
###.#.###.#.#.###.#.#####.#.#.#.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#.###v###################.#.#######.#.#########.#.###.#####.###.#.#.#.###.#.###
|
||||
###...###.#.#.#...#.#.....#...#.#.#...#.#.#.#.#.#.#.#.#.#.#...#...>.>.........#...#.....#.....#...#...#.......#.....#.....#...#...#...#...###
|
||||
#########v#.#.#.###.#.#########.#.#.###.#.#.#.#.#.#.#.#.#.#########v#########.#.#.#.#########.#.#####.#.#############.#####.#########.#######
|
||||
#...#...#.>.#.#...#.#.........#.#.#.#...#.#.#.#.#.#.#.#.#.#.........###.......#.#.#.....#.....#.....#.#...#.........#...#...#.........#...###
|
||||
#.#.#.#.#v###.###.#.#########.#.#.#.#.###.#.#.#.#.#.#.#.#.#.###########.#######.#.#####.#.#########.#.###.#.#######.###.#.###.#########.#.###
|
||||
#.#...#...###.....#.#...#.....#.#...#...#.#.#.#.#.#...#...#...#.....#...#.....#.#.#.....#.......###.#.###...#...#...#...#...#.#...#.....#...#
|
||||
#.#################.#.#.#.#####.#######.#.#.#.#.#.###########.#.###.#.###.###.#.#.#.###########.###.#.#######.#.#.###.#####.#.#.#.#.#######.#
|
||||
#.............#.....#.#.#.....#.....###...#.#.#.#.###...#...#...#...#...#.#...#.#.#.#.....#...#...#.#.#.......#...###...#...#...#...#.......#
|
||||
#############.#.#####.#.#####v#####.#######.#.#.#.###.#.#.#.#####.#####.#.#.###.#.#v#.###.#.#.###.#.#.#.###############.#.###########.#######
|
||||
#.............#.#...#.#...#.>.>.....#.....#.#.#.#.#...#...#.......#####.#.#.....#.>.>.###.#.#.....#.#.#.......#.....###.#...#.......#.......#
|
||||
#.#############.#.#.#.###.#.#v#######.###.#.#.#.#.#.###################.#.#########v#####.#.#######.#.#######.#.###.###.###.#.#####.#######.#
|
||||
#.........#...#...#.#.###.#.#.........#...#...#...#.......#.........#...#...#.......#...#...#...###.#.#.....#...#...#...#...#.....#.........#
|
||||
#########.#.#.#####.#.###.#.###########.#################.#.#######.#.#####.#.#######.#.#####.#.###.#.#.###.#####.###.###.#######.###########
|
||||
#.........#.#.#...#...###...#.........#.#...#...#.......#...#...#...#.#.....#.......#.#.......#...#...#...#.#...#...#.....#...###...........#
|
||||
#.#########.#.#.#.###########.#######.#.#.#.#.#.#.#####.#####.#.#.###.#.###########.#.###########.#######.#.#.#.###.#######.#.#############.#
|
||||
#...#...#...#.#.#.#...#.......#...###...#.#.#.#.#.....#...#...#...###...#...###...#.#.#...........#...#...#...#.....#...###.#.#...#.......#.#
|
||||
###.#.#.#.###.#.#v#.#.#.#######.#.#######.#.#.#.#####.###.#.#############.#.###.#.#.#.#.###########.#.#.#############.#.###.#.#.#.#.#####.#.#
|
||||
#...#.#.#.#...#.#.>.#.#.....#...#...#...#.#.#.#.#...#.#...#.......#...#...#.#...#.#...#.....#.....#.#...#.....###...#.#.#...#.#.#.#...###...#
|
||||
#.###.#.#.#.###.#v###.#####.#.#####.#.#.#.#.#.#.#.#.#.#.#########.#.#.#.###.#.###.#########.#.###.#.#####.###.###.#.#.#.#.###.#.#.###v#######
|
||||
#.....#.#.#...#.#.#...#...#...###...#.#.#.#.#.#.#.#...#.#.......#.#.#.#...#.#...#.###...#...#.#...#...#...###...#.#...#.#...#.#.#...>.###...#
|
||||
#######.#.###.#.#.#.###.#.#######.###.#.#.#.#.#.#.#####.#.#####.#.#.#.###.#.###.#.###.#.#v###.#.#####.#.#######.#.#####.###.#.#.#####v###.#.#
|
||||
#...###...###...#.#...#.#...#...#.###.#.#.#.#.#.#.....#.#.#.....#.#.#.#...#...#.#.#...#.>.>.#.#.....#...#.......#.#.....#...#.#...#...###.#.#
|
||||
#.#.#############.###.#.###.#.#.#v###.#.#.#.#.#.#####.#.#.#.#####v#.#.#.#####.#.#.#.#####v#.#.#####.#####.#######.#.#####.###.###.#.#####.#.#
|
||||
#.#.#...#.....#...###.#.#...#.#.>.>.#.#.#.#.#.#...#...#.#.#.#...>.>.#.#.....#.#.#.#.#.....#...#.....#...#.....#...#.....#...#.#...#.......#.#
|
||||
#.#.#.#.#.###.#.#####.#.#.###.###v#.#.#.#.#.#.###.#.###.#.#.#.###v###.#####.#.#.#.#.#.#########.#####.#.#####.#.#######.###.#.#.###########.#
|
||||
#.#.#.#.#...#.#...#...#.#...#.#...#...#.#.#.#.###...#...#.#.#.#...###...#...#.#.#.#.#.......#...###...#...###.#.......#.#...#.#.#.....#...#.#
|
||||
#.#.#.#.###.#.###.#.###.###.#.#.#######.#.#.#.#######.###.#.#.#.#######.#.###.#.#.#.#######.#.#####.#####.###.#######.#.#.###.#.#.###.#.#.#.#
|
||||
#.#...#.#...#.#...#...#...#...#.......#.#.#.#...#.....#...#...#.......#.#...#...#...#...#...#.......#.....#...#...#...#.#.###...#...#...#...#
|
||||
#.#####.#.###.#.#####.###.###########.#.#.#.###.#.#####.#############.#.###.#########.#.#.###########.#####.###.#.#.###.#.#########.#########
|
||||
#.#...#...###...#.....#...#...........#...#.....#...#...#...#...#...#.#.#...#...#...#.#.#...#.........#...#...#.#.#...#...#####...#.........#
|
||||
#.#.#.###########.#####.###.#######################.#.###.#.#.#.#.#.#.#.#.###.#.#.#.#.#.###.#.#########.#.###v#.#.###.#########.#.#########.#
|
||||
#...#.........###.....#...#.......###...#.........#...#...#...#...#.#.#...#...#...#...#.....#.....#...#.#.#.>.>.#...#.#.........#...........#
|
||||
#############.#######.###.#######.###.#.#.#######.#####.###########.#.#####.#####################.#.#.#.#.#.#v#####.#.#.#####################
|
||||
#.............#...###.....#.....#.....#...#...#...#.....#.......#...#.#...#.................#.....#.#...#...#...###...#.#...#...#.......#...#
|
||||
#.#############.#.#########.###.###########.#.#.###.#####.#####.#.###.#.#.#################.#.#####.###########.#######.#.#.#.#.#.#####.#.#.#
|
||||
#.#.....#...###.#.....#...#...#...........#.#...###.......#...#.#...#.#.#.#.........#...#...#...#...#.......#...#...###...#...#...#...#...#.#
|
||||
#.#.###.#.#.###.#####.#.#.###.###########.#.###############.#.#.###.#.#.#.#.#######.#.#.#.#####.#.###.#####.#.###.#.###############.#.#####.#
|
||||
#...###...#...#...#...#.#.###.........#...#.......#.........#.#.#...#.#.#.#.......#.#.#.#.#...#...###.....#.#.....#...#.............#.....#.#
|
||||
#############.###.#.###.#.###########.#.#########.#.#########.#.#.###.#.#.#######.#.#.#.#.#.#.###########.#.#########.#.#################.#.#
|
||||
#...###.......#...#...#.#.#...........#.....#.....#.........#...#.....#.#.........#.#.#.#.#.#.............#...#.......#.................#.#.#
|
||||
#.#.###v#######.#####.#.#.#.###############.#.#############.###########.###########.#.#.#.#.#################.#.#######################.#.#.#
|
||||
#.#...#.>.#.....#.....#.#.#...............#.#...#...#######.....#...###...........#.#.#.#.#.#.......#...#####...###.....#...#...###.....#.#.#
|
||||
#.###.#v#.#.#####.#####.#.###############.#.###.#.#.###########.#.#.#############.#.#.#.#.#.#.#####.#.#.###########.###.#.#.#.#.###.#####.#.#
|
||||
#...#...#...#.....#...#.#...#.............#.#...#.#.###.........#.#.#...###.......#...#...#...###...#.#...#...#...#...#.#.#.#.#...#.....#...#
|
||||
###.#########.#####.#.#.###.#.#############.#.###.#.###.#########.#.#.#.###.#####################.###.###.#.#.#.#.###.#.#.#.#.###.#####.#####
|
||||
#...#.......#.....#.#.#.#...#.....#...#...#...###.#...#.......#...#...#...#.........#...#...#...#.....#...#.#.#.#.###.#.#.#.#.#...#.....#...#
|
||||
#.###.#####.#####.#.#.#.#.#######.#.#.#.#.#######.###.#######.#.#########.#########.#.#.#.#.#.#.#######.###.#.#.#.###.#.#.#.#.#.###v#####.#.#
|
||||
#.....#.....#...#...#...#...#.....#.#...#.#.......#...#.......#...#.......#.........#.#.#.#.#.#.#...###.###.#.#.#.#...#.#.#.#.#.#.>.###...#.#
|
||||
#######.#####.#.###########.#.#####.#####.#.#######.###.#########.#.#######.#########.#.#.#.#.#.#.#.###v###.#.#.#.#.###.#.#.#.#.#.#v###.###.#
|
||||
#.......#.....#.#...#.......#.......#.....#.......#.###.....#...#.#...#...#.....###...#.#.#.#.#.#.#.#.>.>...#.#.#...###.#.#.#.#...#...#.#...#
|
||||
#.#######.#####.#.#.#.###############.###########.#.#######.#.#.#.###.#.#.#####.###.###.#.#.#.#.#.#.#.#v#####.#.#######.#.#.#.#######.#.#.###
|
||||
#.......#.#.....#.#.#.....#.....#.....#...#...#...#...#...#.#.#.#.#...#.#.#...#.#...###.#.#...#.#.#...#.....#.#.......#.#.#.#...#.....#.#...#
|
||||
#######.#.#.#####.#.#####.#.###.#.#####.#.#.#.#.#####.#.#.#.#.#.#.#.###.#.#.#.#v#.#####.#.#####.#.#########.#.#######.#.#.#.###.#.#####.###.#
|
||||
#.......#.#...#...#...#...#...#.#.#...#.#.#.#.#...#...#.#.#.#.#.#.#...#.#.#.#.>.>.###...#.....#.#.###.......#.#.......#.#.#.#...#.......#...#
|
||||
#.#######.###.#.#####.#.#####.#.#v#.#.#.#.#.#.###.#.###.#.#v#.#.#.###.#.#.#.###v#####.#######.#.#.###.#######.#.#######.#.#.#.###########.###
|
||||
#...#...#...#.#.#.....#.#...#.#.>.>.#.#.#...#.#...#...#.#.>.>.#.#.#...#.#...###.....#...#...#.#.#.#...#.....#.#.....###...#.#...#.........###
|
||||
###.#.#.###.#.#.#.#####.#.#.#.###v###.#.#####.#.#####.#.###v###.#.#.###.###########.###.#.#.#.#.#.#.###.###.#.#####.#######.###.#.###########
|
||||
###.#.#.#...#...#.....#...#...###.#...#.....#...#.....#.###...#...#.....#...#...#...#...#.#.#.#.#.#...#.#...#...#...#...###.....#...........#
|
||||
###.#.#.#.###########.###########.#.#######.#####.#####.#####.###########.#.#.#.#.###.###.#.#.#.#.###.#.#.#####.#.###.#.###################.#
|
||||
#...#.#.#.#...........###...#.....#...#...#.....#.#.....#####.......#.....#...#.#...#.#...#...#...###...#.....#.#.###.#.#...#...#...........#
|
||||
#.###.#.#.#.#############.#.#.#######.#.#.#####.#.#.###############.#.#########.###.#.#.#####################.#.#.###.#.#.#.#.#.#.###########
|
||||
#...#.#.#.#.#...........#.#.#.#.....#.#.#.#.....#...#...............#...#...###.....#.#...#.................#.#.#.#...#...#.#.#.#.........###
|
||||
###.#.#.#.#.#.#########.#.#.#.#.###.#.#.#.#.#########.#################.#.#.#########.###.#.###############.#.#.#.#.#######.#.#.#########.###
|
||||
###.#.#.#.#.#.#.......#...#.#...#...#.#.#.#...#...#...#...#.......#...#...#.........#.....#...............#...#...#...#.....#.#.#...#...#...#
|
||||
###.#.#.#.#.#.#.#####.#####.#####.###.#.#.###.#.#.#.###.#.#.#####.#.#.#############.#####################.###########.#.#####.#.#.#.#v#.###.#
|
||||
###.#.#.#.#...#.....#.#...#.#...#.###...#.....#.#.#...#.#...#.....#.#.#.............###...#...#.....#...#.#.......#...#...#...#.#.#.>.#.....#
|
||||
###.#.#.#.#########.#.#.#.#.#.#.#.#############.#.###.#.#####.#####.#.#.###############.#.#.#.#.###.#.#.#.#.#####.#.#####.#.###.#.###v#######
|
||||
###...#...#.....#...#...#...#.#.#...........###.#.###...#.....###...#.#.......#.......#.#.#.#.#...#...#.#.#.....#...###...#...#...#...#...###
|
||||
###########.###.#.###########.#.###########.###.#.#######.#######.###.#######.#.#####.#.#.#.#.###.#####.#.#####.#######.#####.#####.###.#.###
|
||||
#.......###...#...#...###.....#.............#...#.......#.......#.#...#...#...#.#.....#.#.#.#.###.....#...#...#.......#.......#...#.....#...#
|
||||
#.#####.#####.#####.#.###.###################.#########.#######.#.#.###.#.#.###.#.#####.#.#.#.#######.#####.#.#######.#########.#.#########.#
|
||||
#.....#.......#...#.#...#.........#...###...#...#.......#...#...#.#...#.#...#...#.#...#.#.#.#.#...#...#...#.#.###...#...###.....#...........#
|
||||
#####.#########.#.#.###.#########v#.#.###.#.###.#.#######.#.#.###.###.#.#####.###.#.#.#.#.#.#.#.#.#.###.#.#.#.###.#.###.###.#################
|
||||
#.....#.......#.#.#.###...#...#.>.>.#...#.#.#...#...#.....#...###...#.#.....#.#...#.#.#.#.#.#.#.#.#...#.#.#.#.#...#.....#...#.....#.....#####
|
||||
#.#####.#####.#.#.#.#####.#.#.#.#######.#.#.#.#####.#.#############.#.#####v#.#.###.#.#.#.#.#.#.#.###v#.#.#.#.#.#########.###.###.#.###.#####
|
||||
#.....#.#.....#.#.#.#####.#.#...#.......#.#.#...#...#.........###...#.#...>.>.#.#...#.#.#...#.#.#...>.>.#.#.#.#.........#...#.#...#.###...###
|
||||
#####.#.#.#####.#.#.#####.#.#####.#######.#.###.#.###########v###.###.#.#######.#.###.#.#####.#.#########.#.#.#########.###.#.#.###.#####.###
|
||||
#####...#.....#.#...#.....#.....#.......#.#...#.#...#...#...>.>.#.###.#.....###.#.###.#.###...#.......#...#.#.#.......#.#...#.#.....#...#...#
|
||||
#############.#.#####.#########.#######.#.###.#.###.#.#.#.#####.#.###.#####.###.#.###.#.###.#########.#.###.#.#.#####.#.#.###.#######.#.###.#
|
||||
#.............#...#...#...#.....#.......#.#...#...#.#.#.#.....#.#.#...#.....#...#...#.#...#.....#.....#...#.#.#.....#.#.#...#.#.......#.....#
|
||||
#.###############.#.###.#.#.#####.#######.#.#####.#.#.#.#####.#.#.#.###.#####.#####.#.###.#####.#.#######.#.#.#####.#.#.###.#.#.#############
|
||||
#.................#.....#...#####.........#.......#...#.......#...#.....#####.......#.....#####...#######...#.......#...###...#.............#
|
||||
###########################################################################################################################################.#
|
||||
236
day23/main.go
Normal file
236
day23/main.go
Normal file
@@ -0,0 +1,236 @@
|
||||
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) {
|
||||
var m aoc.Map[int16, rune]
|
||||
|
||||
start := Point{0, 0}
|
||||
target := Point{0, 0}
|
||||
var text string
|
||||
for scan.Scan() {
|
||||
text = scan.Text()
|
||||
if start == target {
|
||||
start[1] = int16(strings.IndexRune(text, '.'))
|
||||
}
|
||||
m = append(m, []rune(text))
|
||||
}
|
||||
target[0] = int16(len(m) - 1)
|
||||
target[1] = int16(strings.IndexRune(text, '.'))
|
||||
|
||||
result := &result{}
|
||||
|
||||
result.valuePT1 = search(&graph{m: m, start: start, target: target, neighbors: part1nbs})
|
||||
result.valuePT2 = search(&graph{m: m, start: start, target: target, neighbors: part2nbs})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type Point = aoc.Point[int16]
|
||||
type Map = aoc.Map[int16, rune]
|
||||
|
||||
// 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 dirIDX = func() map[Point]direction {
|
||||
m := make(map[Point]direction, len(directions))
|
||||
for k, v := range directions {
|
||||
m[v] = direction(k)
|
||||
}
|
||||
return m
|
||||
}()
|
||||
|
||||
var arrows = []rune{'^', '>', 'v', '<'}
|
||||
|
||||
var arrowIDX = func() map[rune]Point {
|
||||
m := make(map[rune]Point, len(arrows))
|
||||
for k, v := range arrows {
|
||||
m[v] = directions[k]
|
||||
}
|
||||
return m
|
||||
}()
|
||||
|
||||
// position on the map
|
||||
type position struct {
|
||||
loc Point
|
||||
direction Point
|
||||
}
|
||||
|
||||
func (p position) step(to Point) position {
|
||||
return position{p.loc.Add(to), to}
|
||||
}
|
||||
|
||||
// implements FindPath graph interface
|
||||
type graph struct {
|
||||
m Map
|
||||
start Point
|
||||
target Point
|
||||
|
||||
neighbors func(g *graph, current position) []position
|
||||
}
|
||||
|
||||
// Neighbors returns valid steps from given position. if at target returns none.
|
||||
func (g *graph) Neighbors(current position) []position {
|
||||
return g.neighbors(g, current)
|
||||
}
|
||||
|
||||
// Cost calculates heat cost to neighbor from map
|
||||
func (g *graph) Cost(a, b position) int16 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (g *graph) Target(a position, c int16) bool {
|
||||
return a.loc == g.target
|
||||
}
|
||||
|
||||
func (g *graph) Seen(a position) position {
|
||||
a.direction = Point{}
|
||||
return a
|
||||
}
|
||||
|
||||
func match[T comparable](match T, lis ...T) bool {
|
||||
for _, b := range lis {
|
||||
if b == match {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func search(g *graph) int {
|
||||
costs, paths := aoc.FindPaths[int16, position](g, position{loc: g.start}, position{loc: g.target})
|
||||
|
||||
for i, path := range paths {
|
||||
log("path length = ", costs[i])
|
||||
printGraph(g.m, path)
|
||||
}
|
||||
|
||||
return int(aoc.Max(0, costs...))
|
||||
}
|
||||
|
||||
// printGraph with the path overlay
|
||||
func printGraph(m Map, path []position) {
|
||||
pts := make(map[Point]position, len(path))
|
||||
for _, pt := range path {
|
||||
pts[pt.loc] = pt
|
||||
}
|
||||
|
||||
for r, row := range m {
|
||||
for c, x := range row {
|
||||
if _, ok := pts[Point{int16(r), int16(c)}]; ok {
|
||||
if x == '.' {
|
||||
fmt.Print("*")
|
||||
} else {
|
||||
fmt.Print(string(x))
|
||||
}
|
||||
continue
|
||||
}
|
||||
fmt.Print(".")
|
||||
_ = x
|
||||
// fmt.Print(string(x))
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
func opposite(d Point) Point {
|
||||
return directions[(dirIDX[d]+2)%4]
|
||||
}
|
||||
|
||||
|
||||
func part1nbs(g *graph, current position) []position {
|
||||
var nbs []position
|
||||
|
||||
if current.loc == g.start {
|
||||
return []position{
|
||||
{current.loc.Add(D), D},
|
||||
}
|
||||
}
|
||||
|
||||
if current.loc == g.target {
|
||||
return nil
|
||||
}
|
||||
|
||||
// only one direction on arrow.
|
||||
_, r, _ := g.m.Get(current.loc)
|
||||
if match(r, arrows...) {
|
||||
to := arrowIDX[r]
|
||||
if next := current.step(to); g.m.Valid(next.loc) {
|
||||
_, r, _ := g.m.Get(next.loc)
|
||||
d := arrows[(dirIDX[to]+2)%4] // flow from opposite direction
|
||||
if !match(r, rune(d), '#') {
|
||||
nbs = append(nbs, next)
|
||||
}
|
||||
}
|
||||
return nbs
|
||||
}
|
||||
|
||||
for _, to := range directions {
|
||||
if next := current.step(to); g.m.Valid(next.loc) {
|
||||
_, r, _ := g.m.Get(next.loc)
|
||||
d := arrows[(dirIDX[to]+2)%4] // flow from opposite direction
|
||||
if !match(r, rune(d), '#') {
|
||||
nbs = append(nbs, next)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbs
|
||||
}
|
||||
|
||||
func part2nbs(g *graph, current position) []position {
|
||||
var nbs []position
|
||||
|
||||
if current.loc == g.start {
|
||||
return []position{
|
||||
{current.loc.Add(D), D},
|
||||
}
|
||||
}
|
||||
|
||||
if current.loc == g.target {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, to := range directions {
|
||||
if next := current.step(to); g.m.Valid(next.loc) {
|
||||
if next.direction == opposite(current.direction) {
|
||||
continue
|
||||
}
|
||||
_, r, _ := g.m.Get(next.loc)
|
||||
if r == '#' {
|
||||
continue
|
||||
}
|
||||
|
||||
nbs = append(nbs, next)
|
||||
}
|
||||
}
|
||||
return nbs
|
||||
}
|
||||
42
day23/main_test.go
Normal file
42
day23/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, 94)
|
||||
is.Equal(result.valuePT2, 154)
|
||||
}
|
||||
|
||||
// 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 > 1918)
|
||||
// is.Equal(result.valuePT1, 2074)
|
||||
// is.Equal(result.valuePT2, 0)
|
||||
// }
|
||||
11
go.mod
11
go.mod
@@ -1,5 +1,10 @@
|
||||
module go.sour.is/advent-of-code-2023
|
||||
module go.sour.is/advent-of-code
|
||||
|
||||
go 1.21.3
|
||||
go 1.21.4
|
||||
|
||||
require github.com/matryer/is v1.4.1
|
||||
toolchain go1.21.5
|
||||
|
||||
require (
|
||||
github.com/matryer/is v1.4.1
|
||||
golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611
|
||||
)
|
||||
|
||||
2
go.sum
2
go.sum
@@ -1,2 +1,4 @@
|
||||
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
|
||||
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4=
|
||||
golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
||||
|
||||
247
grids.go
Normal file
247
grids.go
Normal file
@@ -0,0 +1,247 @@
|
||||
package aoc
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
type Vector struct {
|
||||
Offset Point[int]
|
||||
Scale int
|
||||
}
|
||||
|
||||
func (v Vector) Point() Point[int] {
|
||||
return v.Offset.Scale(v.Scale)
|
||||
}
|
||||
|
||||
type Point[T integer] [2]T
|
||||
|
||||
func (p Point[T]) Add(a Point[T]) Point[T] {
|
||||
return Point[T]{p[0] + a[0], p[1] + a[1]}
|
||||
}
|
||||
func (p Point[T]) Scale(m T) Point[T] {
|
||||
return Point[T]{p[0] * m, p[1] * m}
|
||||
}
|
||||
func (p Point[T]) Less(b Point[T]) bool {
|
||||
if p[0] != b[0] {
|
||||
return p[0] < b[0]
|
||||
}
|
||||
return p[1] < b[1]
|
||||
}
|
||||
|
||||
func Transpose[T any](matrix [][]T) [][]T {
|
||||
rows, cols := len(matrix), len(matrix[0])
|
||||
|
||||
m := make([][]T, cols)
|
||||
for i := range m {
|
||||
m[i] = make([]T, rows)
|
||||
}
|
||||
|
||||
for i := 0; i < cols; i++ {
|
||||
for j := 0; j < rows; j++ {
|
||||
m[i][j] = matrix[j][i]
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// NumPoints the number of the points inside an outline plus the number of points in the outline
|
||||
func NumPoints(outline []Point[int], borderLength int) int {
|
||||
// shoelace - find the float area in a shape
|
||||
sum := 0
|
||||
for _, p := range Pairwise(outline) {
|
||||
row1, col1 := p[0][0], p[0][1]
|
||||
row2, col2 := p[1][0], p[1][1]
|
||||
|
||||
sum += row1*col2 - row2*col1
|
||||
}
|
||||
area := sum / 2
|
||||
|
||||
// pick's theorem - find the number of points in a shape given its area
|
||||
return (ABS(area) - borderLength/2 + 1) + borderLength
|
||||
}
|
||||
|
||||
type Map[I integer, T any] [][]T
|
||||
|
||||
func (m *Map[I, T]) Get(p Point[I]) (Point[I], T, bool) {
|
||||
var zero T
|
||||
if !m.Valid(p) {
|
||||
return [2]I{0, 0}, zero, false
|
||||
}
|
||||
|
||||
return p, (*m)[p[0]][p[1]], true
|
||||
}
|
||||
func (m *Map[I, T]) Size() (I, I) {
|
||||
if m == nil || len(*m) == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
return I(len(*m)), I(len((*m)[0]))
|
||||
}
|
||||
func (m *Map[I, T]) Valid(p Point[I]) bool {
|
||||
rows, cols := m.Size()
|
||||
return p[0] >= 0 && p[0] < rows && p[1] >= 0 && p[1] < cols
|
||||
}
|
||||
|
||||
type cmap[C number, N comparable] struct {
|
||||
base pather[C, N]
|
||||
neighbors map[N]map[N]C
|
||||
}
|
||||
|
||||
func (m *cmap[C, N]) Cost(a, b N) C {
|
||||
if v, ok := m.neighbors[a]; ok {
|
||||
return v[b]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func (m *cmap[C, N]) Neighbors(n N) []N {
|
||||
if v, ok := m.neighbors[n]; ok {
|
||||
return maps.Keys(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *cmap[C, N]) Target(n N, c C) bool {
|
||||
return m.base.Target(n, c)
|
||||
}
|
||||
func (m *cmap[C, N]) String() string {
|
||||
var b = &strings.Builder{}
|
||||
|
||||
for k, nbs := range m.neighbors {
|
||||
fmt.Fprintln(b, k)
|
||||
for to, v := range nbs {
|
||||
fmt.Fprintln(b, " ", to, v)
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func CompressMap[C number, N comparable](p pather[C, N], start N) pather[C, N] {
|
||||
var next = []N{start}
|
||||
var visited = make(map[N]map[N]C)
|
||||
|
||||
var n N
|
||||
for len(next) > 0 {
|
||||
n, next = next[len(next)-1], next[:len(next)-1]
|
||||
|
||||
if _, ok := visited[n]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
nbs := p.Neighbors(n)
|
||||
if len(nbs) == 2{
|
||||
a, b := nbs[0], nbs[1]
|
||||
if to, ok := visited[a]; ok {
|
||||
to[b] = to[n] + p.Cost(n, b)
|
||||
delete(to, n)
|
||||
visited[a] = to
|
||||
continue
|
||||
} else if to, ok := visited[b]; ok {
|
||||
to[a] = to[n] + p.Cost(n, a)
|
||||
delete(to, n)
|
||||
visited[b] = to
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
visited[n] = make(map[N]C)
|
||||
next = append(next, nbs...)
|
||||
for _, to := range nbs {
|
||||
visited[n][to] = p.Cost(n, to)
|
||||
}
|
||||
}
|
||||
|
||||
return &cmap[C, N]{base: p, neighbors: visited}
|
||||
}
|
||||
|
||||
type adjacencyList[V any, C comparable] map[C][]V
|
||||
type graph[V any, W cmp.Ordered, C comparable] map[C]*vertex[V, W]
|
||||
type graphOption[V any, W cmp.Ordered, C comparable] func(g *graph[V, W, C])
|
||||
type vertex[V any, W cmp.Ordered] struct {
|
||||
Value V
|
||||
Edges edges[V, W]
|
||||
}
|
||||
|
||||
func (v *vertex[V, W]) Neighbors() []V {
|
||||
var nbs []V
|
||||
sort.Sort(v.Edges)
|
||||
for _, e := range v.Edges {
|
||||
nbs = append(nbs, e.Vertex.Value)
|
||||
}
|
||||
return nbs
|
||||
}
|
||||
|
||||
type edge[V any, W cmp.Ordered] struct {
|
||||
Vertex *vertex[V, W]
|
||||
Weight W
|
||||
}
|
||||
type edges[V any, W cmp.Ordered] []edge[V, W]
|
||||
|
||||
func (e edges[V, W]) Len() int { return len(e) }
|
||||
func (e edges[V, W]) Less(i, j int) bool { return e[i].Weight < e[j].Weight }
|
||||
func (e edges[V, W]) Swap(i, j int) { e[i], e[j] = e[j], e[i] }
|
||||
|
||||
func Graph[V any, W cmp.Ordered, C comparable](opts ...graphOption[V, W, C]) *graph[V, W, C] {
|
||||
g := make(graph[V, W, C])
|
||||
for _, opt := range opts {
|
||||
opt(&g)
|
||||
}
|
||||
return &g
|
||||
}
|
||||
func (g *graph[V, W, C]) AddVertex(id C, value V) {
|
||||
(*g)[id] = &vertex[V, W]{Value: value}
|
||||
}
|
||||
func (g *graph[V, W, C]) AddEdge(from, to C, w W) {
|
||||
if g == nil {
|
||||
return
|
||||
}
|
||||
if _, ok := (*g)[from]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := (*g)[to]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
(*g)[from].Edges = append((*g)[from].Edges, edge[V, W]{(*g)[to], w})
|
||||
}
|
||||
func (g *graph[V, W, C]) Neighbors(v C) []V {
|
||||
if g == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return (*g)[v].Neighbors()
|
||||
}
|
||||
func (g *graph[V, W, C]) AdjacencyList() adjacencyList[V, C] {
|
||||
m := make(map[C][]V)
|
||||
for id, v := range *g {
|
||||
if len(v.Edges) == 0 {
|
||||
continue
|
||||
}
|
||||
m[id] = v.Neighbors()
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func WithAdjacencyList[W cmp.Ordered, C comparable](list adjacencyList[C, C]) graphOption[C, W, C] {
|
||||
var zeroW W
|
||||
return func(g *graph[C, W, C]) {
|
||||
for vertex, edges := range list {
|
||||
if _, ok := (*g)[vertex]; !ok {
|
||||
g.AddVertex(vertex, vertex)
|
||||
}
|
||||
|
||||
// add edges to vertex
|
||||
for _, edge := range edges {
|
||||
// add edge as vertex, if not added
|
||||
if _, ok := (*g)[edge]; !ok {
|
||||
g.AddVertex(edge, edge)
|
||||
}
|
||||
|
||||
g.AddEdge(vertex, edge, zeroW) // no weights in this adjacency list
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
56
itertools.go
Normal file
56
itertools.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package aoc
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func Atoi(s string) int {
|
||||
i, _ := strconv.Atoi(s)
|
||||
return i
|
||||
}
|
||||
|
||||
func Repeat[T any](s T, i int) []T {
|
||||
lis := make([]T, i)
|
||||
for i := range lis {
|
||||
lis[i] = s
|
||||
}
|
||||
return lis
|
||||
}
|
||||
|
||||
func Reduce[T, U any](fn func(int, T, U) U, u U, list ...T) U {
|
||||
for i, t := range list {
|
||||
u = fn(i, t, u)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func Reverse[T any](arr []T) []T {
|
||||
for i := 0; i < len(arr)/2; i++ {
|
||||
arr[i], arr[len(arr)-i-1] = arr[len(arr)-i-1], arr[i]
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
func SliceMap[T, U any](fn func(T) U, in ...T) []U {
|
||||
lis := make([]U, len(in))
|
||||
for i := range lis {
|
||||
lis[i] = fn(in[i])
|
||||
}
|
||||
return lis
|
||||
}
|
||||
func SliceIMap[T, U any](fn func(int, T) U, in ...T) []U {
|
||||
lis := make([]U, len(in))
|
||||
for i := range lis {
|
||||
lis[i] = fn(i, in[i])
|
||||
}
|
||||
return lis
|
||||
}
|
||||
|
||||
// Pairwise iterates over a list pairing i, i+1
|
||||
func Pairwise[T any](arr []T) [][2]T {
|
||||
var pairs [][2]T
|
||||
for i := range arr[:len(arr)-1] {
|
||||
pairs = append(pairs, [2]T{arr[i], arr[i+1]})
|
||||
}
|
||||
return pairs
|
||||
}
|
||||
44
itertools_test.go
Normal file
44
itertools_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package aoc_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matryer/is"
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
func TestReverse(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
is.Equal(aoc.Reverse([]int{1, 2, 3, 4}), []int{4, 3, 2, 1})
|
||||
}
|
||||
|
||||
func TestReadStringToInts(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
is.Equal(aoc.ReadStringToInts([]string{"1", "2", "3"}), []int{1, 2, 3})
|
||||
}
|
||||
|
||||
func TestRepeat(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
is.Equal(aoc.Repeat(5, 3), []int{5, 5, 5})
|
||||
}
|
||||
|
||||
func TestTranspose(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
is.Equal(
|
||||
aoc.Transpose(
|
||||
[][]int{
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
},
|
||||
),
|
||||
[][]int{
|
||||
{1, 0, 1},
|
||||
{1, 0, 1},
|
||||
},
|
||||
)
|
||||
}
|
||||
100
lists.go
Normal file
100
lists.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package aoc
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Node[T any] struct {
|
||||
value T
|
||||
pos int
|
||||
left *Node[T]
|
||||
}
|
||||
|
||||
func (n *Node[T]) add(a *Node[T]) *Node[T] {
|
||||
if a == nil {
|
||||
return n
|
||||
}
|
||||
|
||||
if n == nil {
|
||||
return a
|
||||
}
|
||||
|
||||
n.left = a
|
||||
return a
|
||||
}
|
||||
|
||||
func (n *Node[T]) Value() (value T, ok bool) {
|
||||
if n == nil {
|
||||
return
|
||||
}
|
||||
return n.value, true
|
||||
}
|
||||
|
||||
func (n *Node[T]) Position() int {
|
||||
if n == nil {
|
||||
return -1
|
||||
}
|
||||
return n.pos
|
||||
}
|
||||
func (n *Node[T]) SetPosition(i int) {
|
||||
if n == nil {
|
||||
return
|
||||
}
|
||||
n.pos = i
|
||||
}
|
||||
func (n *Node[T]) Next() *Node[T] {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
return n.left
|
||||
}
|
||||
|
||||
func (n *Node[T]) String() string {
|
||||
if n == nil {
|
||||
return "EOL"
|
||||
}
|
||||
return fmt.Sprintf("node %v", n.value)
|
||||
}
|
||||
|
||||
type List[T any] struct {
|
||||
head *Node[T]
|
||||
n *Node[T]
|
||||
p map[int]*Node[T]
|
||||
}
|
||||
|
||||
func NewList[T any](a *Node[T]) *List[T] {
|
||||
lis := &List[T]{
|
||||
head: a,
|
||||
n: a,
|
||||
p: make(map[int]*Node[T]),
|
||||
}
|
||||
lis.add(a)
|
||||
|
||||
return lis
|
||||
}
|
||||
func (l *List[T]) Add(value T, pos int) {
|
||||
a := &Node[T]{value: value, pos: pos}
|
||||
l.add(a)
|
||||
}
|
||||
func (l *List[T]) add(a *Node[T]) {
|
||||
if l.head == nil {
|
||||
l.head = a
|
||||
}
|
||||
if a == nil {
|
||||
return
|
||||
}
|
||||
|
||||
l.n = l.n.add(a)
|
||||
l.p[a.pos] = a
|
||||
}
|
||||
func (l *List[T]) Get(pos int) *Node[T] {
|
||||
return l.p[pos]
|
||||
}
|
||||
func (l *List[T]) GetN(pos ...int) []*Node[T] {
|
||||
lis := make([]*Node[T], len(pos))
|
||||
for i, p := range pos {
|
||||
lis[i] = l.p[p]
|
||||
}
|
||||
return lis
|
||||
}
|
||||
func (l *List[T]) Head() *Node[T] {
|
||||
return l.head
|
||||
}
|
||||
96
math.go
Normal file
96
math.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package aoc
|
||||
|
||||
import "cmp"
|
||||
|
||||
type uinteger interface {
|
||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
|
||||
}
|
||||
type sinteger interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64
|
||||
}
|
||||
type integer interface {
|
||||
sinteger | uinteger
|
||||
}
|
||||
|
||||
type float interface {
|
||||
complex64 | complex128 | float32 | float64
|
||||
}
|
||||
type number interface{ integer | float }
|
||||
|
||||
// greatest common divisor (GCD) via Euclidean algorithm
|
||||
func GCD[T integer](a, b T) T {
|
||||
for b != 0 {
|
||||
t := b
|
||||
b = a % b
|
||||
a = t
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// find Least Common Multiple (LCM) via GCD
|
||||
func LCM[T integer](integers ...T) T {
|
||||
if len(integers) == 0 {
|
||||
return 0
|
||||
}
|
||||
if len(integers) == 1 {
|
||||
return integers[0]
|
||||
}
|
||||
|
||||
a, b := integers[0], integers[1]
|
||||
result := a * b / GCD(a, b)
|
||||
|
||||
for _, c := range integers[2:] {
|
||||
result = LCM(result, c)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func Sum[T number](arr ...T) T {
|
||||
var acc T
|
||||
for _, a := range arr {
|
||||
acc += a
|
||||
}
|
||||
return acc
|
||||
}
|
||||
func SumFunc[T any, U number](fn func(T) U, input ...T) U {
|
||||
return Sum(SliceMap(fn, input...)...)
|
||||
}
|
||||
func SumIFunc[T any, U number](fn func(int, T) U, input ...T) U {
|
||||
return Sum(SliceIMap(fn, input...)...)
|
||||
}
|
||||
|
||||
func Power2(n int) int {
|
||||
if n == 0 {
|
||||
return 1
|
||||
}
|
||||
p := 2
|
||||
for ; n > 1; n-- {
|
||||
p *= 2
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func ABS[I integer](i I) I {
|
||||
if i < 0 {
|
||||
return -i
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func Max[T cmp.Ordered](a T, v ...T) T {
|
||||
for _, b := range v {
|
||||
if b > a {
|
||||
a = b
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
func Min[T cmp.Ordered](a T, v ...T) T {
|
||||
for _, b := range v {
|
||||
if b < a {
|
||||
a = b
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
33
math_test.go
Normal file
33
math_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package aoc_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matryer/is"
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
func TestLCM(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
is.Equal(aoc.LCM([]int{}...), 0)
|
||||
is.Equal(aoc.LCM(5), 5)
|
||||
is.Equal(aoc.LCM(5, 3), 15)
|
||||
is.Equal(aoc.LCM(5, 3, 2), 30)
|
||||
}
|
||||
|
||||
func TestPower2(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
is.Equal(aoc.Power2(0), 1)
|
||||
is.Equal(aoc.Power2(1), 2)
|
||||
is.Equal(aoc.Power2(2), 4)
|
||||
}
|
||||
|
||||
func TestABS(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
is.Equal(aoc.ABS(1), 1)
|
||||
is.Equal(aoc.ABS(0), 0)
|
||||
is.Equal(aoc.ABS(-1), 1)
|
||||
}
|
||||
94
runner.go
Normal file
94
runner.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package aoc
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
|
||||
var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
|
||||
|
||||
func Runner[R any, F func(*bufio.Scanner) (R, error)](run F) (R, error) {
|
||||
if len(os.Args) < 2 {
|
||||
Log("Usage:", filepath.Base(os.Args[0]), "FILE")
|
||||
os.Exit(22)
|
||||
}
|
||||
|
||||
inputFilename := os.Args[1]
|
||||
os.Args = append(os.Args[:1], os.Args[2:]...)
|
||||
|
||||
flag.Parse()
|
||||
Log(cpuprofile, memprofile, *cpuprofile, *memprofile)
|
||||
if *cpuprofile != "" {
|
||||
Log("enabled cpu profile")
|
||||
f, err := os.Create(*cpuprofile)
|
||||
if err != nil {
|
||||
log.Fatal("could not create CPU profile: ", err)
|
||||
}
|
||||
defer f.Close() // error handling omitted for example
|
||||
Log("write cpu profile to", f.Name())
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
log.Fatal("could not start CPU profile: ", err)
|
||||
}
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
if *memprofile != "" {
|
||||
Log("enabled mem profile")
|
||||
defer func() {
|
||||
f, err := os.Create(*memprofile)
|
||||
if err != nil {
|
||||
log.Fatal("could not create memory profile: ", err)
|
||||
}
|
||||
Log("write mem profile to", f.Name())
|
||||
defer f.Close() // error handling omitted for example
|
||||
runtime.GC() // get up-to-date statistics
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
log.Fatal("could not write memory profile: ", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
input, err := os.Open(inputFilename)
|
||||
if err != nil {
|
||||
Log(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
scan := bufio.NewScanner(input)
|
||||
|
||||
return run(scan)
|
||||
}
|
||||
|
||||
func MustResult[T any](result T, err error) {
|
||||
if err != nil {
|
||||
fmt.Println("ERR", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
Log("result", result)
|
||||
}
|
||||
|
||||
func Log(v ...any) {
|
||||
fmt.Fprint(os.Stderr, time.Now(), ": ")
|
||||
fmt.Fprintln(os.Stderr, v...)
|
||||
}
|
||||
func Logf(format string, v ...any) {
|
||||
if !strings.HasSuffix(format, "\n") {
|
||||
format += "\n"
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, format, v...)
|
||||
}
|
||||
|
||||
func ReadStringToInts(fields []string) []int {
|
||||
return SliceMap(Atoi, fields...)
|
||||
}
|
||||
427
search.go
Normal file
427
search.go
Normal file
@@ -0,0 +1,427 @@
|
||||
package aoc
|
||||
|
||||
import (
|
||||
"maps"
|
||||
"math/bits"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type priorityQueue[T any] struct {
|
||||
elems []*T
|
||||
less func(a, b *T) bool
|
||||
maxDepth int
|
||||
totalEnqueue int
|
||||
totalDequeue int
|
||||
}
|
||||
|
||||
// PriorityQueue implements a simple slice based queue.
|
||||
// less is the function for sorting. reverse a and b to reverse the sort.
|
||||
// T is the item
|
||||
// U is a slice of T
|
||||
func PriorityQueue[T any](less func(a, b *T) bool) *priorityQueue[T] {
|
||||
return &priorityQueue[T]{less: less}
|
||||
}
|
||||
func (pq *priorityQueue[T]) Insert(elem *T) {
|
||||
pq.totalEnqueue++
|
||||
|
||||
pq.elems = append(pq.elems, elem)
|
||||
pq.maxDepth = max(pq.maxDepth, len(pq.elems))
|
||||
}
|
||||
func (pq *priorityQueue[T]) IsEmpty() bool {
|
||||
return len(pq.elems) == 0
|
||||
}
|
||||
func (pq *priorityQueue[T]) ExtractMin() *T {
|
||||
pq.totalDequeue++
|
||||
|
||||
var elem *T
|
||||
if pq.IsEmpty() {
|
||||
return elem
|
||||
}
|
||||
|
||||
sort.Slice(pq.elems, func(i, j int) bool { return pq.less(pq.elems[j], pq.elems[i]) })
|
||||
pq.elems, elem = pq.elems[:len(pq.elems)-1], pq.elems[len(pq.elems)-1]
|
||||
return elem
|
||||
}
|
||||
|
||||
// ManhattanDistance the distance between two points measured along axes at right angles.
|
||||
func ManhattanDistance[T integer](a, b Point[T]) T {
|
||||
return ABS(a[0]-b[0]) + ABS(a[1]-b[1])
|
||||
}
|
||||
|
||||
type pather[C number, N comparable] interface {
|
||||
// Neighbors returns all neighbors to node N that should be considered next.
|
||||
Neighbors(N) []N
|
||||
|
||||
// Cost returns
|
||||
Cost(a, b N) C
|
||||
|
||||
// Target returns true when target reached. receives node and cost.
|
||||
Target(N, C) bool
|
||||
|
||||
// OPTIONAL:
|
||||
// Add heuristic for running as A* search.
|
||||
// Potential(N) C
|
||||
|
||||
// Seen modify value used by seen pruning.
|
||||
// Seen(N) N
|
||||
|
||||
}
|
||||
|
||||
// FindPath uses the A* path finding algorithem.
|
||||
// g is the graph source that implements the pather interface.
|
||||
//
|
||||
// C is an numeric type for calculating cost/potential
|
||||
// N is the node values. is comparable for storing in visited table for pruning.
|
||||
//
|
||||
// start, end are nodes that dileniate the start and end of the search path.
|
||||
// The returned values are the calculated cost and the path taken from start to end.
|
||||
func FindPath[C integer, N comparable](g pather[C, N], start, end N) (C, []N, map[N]C) {
|
||||
var zero C
|
||||
|
||||
var seenFn = func(a N) N { return a }
|
||||
if s, ok := g.(interface{ Seen(N) N }); ok {
|
||||
seenFn = s.Seen
|
||||
}
|
||||
|
||||
var potentialFn = func(N) C { var zero C; return zero }
|
||||
if p, ok := g.(interface{ Potential(N) C }); ok {
|
||||
potentialFn = p.Potential
|
||||
}
|
||||
|
||||
type node struct {
|
||||
cost C
|
||||
potential C
|
||||
parent *node
|
||||
position N
|
||||
}
|
||||
|
||||
newPath := func(n *node) []N {
|
||||
var path []N
|
||||
for n.parent != nil {
|
||||
path = append(path, n.position)
|
||||
n = n.parent
|
||||
}
|
||||
path = append(path, n.position)
|
||||
|
||||
Reverse(path)
|
||||
return path
|
||||
}
|
||||
|
||||
less := func(a, b *node) bool {
|
||||
return a.cost+a.potential < b.cost+b.potential
|
||||
}
|
||||
|
||||
closed := make(map[N]C)
|
||||
open := FibHeap(less)
|
||||
|
||||
open.Insert(&node{position: start, potential: potentialFn(start)})
|
||||
closed[start] = zero
|
||||
|
||||
for !open.IsEmpty() {
|
||||
current := open.ExtractMin()
|
||||
for _, nb := range g.Neighbors(current.position) {
|
||||
next := &node{
|
||||
position: nb,
|
||||
parent: current,
|
||||
cost: g.Cost(current.position, nb) + current.cost,
|
||||
potential: potentialFn(nb),
|
||||
}
|
||||
|
||||
seen := seenFn(nb)
|
||||
cost, ok := closed[seen]
|
||||
if !ok || next.cost < cost {
|
||||
open.Insert(next)
|
||||
closed[seen] = next.cost
|
||||
}
|
||||
|
||||
if next.potential == zero && g.Target(next.position, next.cost) {
|
||||
return next.cost, newPath(next), closed
|
||||
}
|
||||
}
|
||||
}
|
||||
return zero, nil, closed
|
||||
}
|
||||
|
||||
type fibTree[T any] struct {
|
||||
value *T
|
||||
parent *fibTree[T]
|
||||
child []*fibTree[T]
|
||||
mark bool
|
||||
}
|
||||
|
||||
func (t *fibTree[T]) Value() *T { return t.value }
|
||||
func (t *fibTree[T]) addAtEnd(n *fibTree[T]) {
|
||||
n.parent = t
|
||||
t.child = append(t.child, n)
|
||||
}
|
||||
|
||||
type fibHeap[T any] struct {
|
||||
trees []*fibTree[T]
|
||||
least *fibTree[T]
|
||||
count uint
|
||||
less func(a, b *T) bool
|
||||
}
|
||||
|
||||
func FibHeap[T any](less func(a, b *T) bool) *fibHeap[T] {
|
||||
return &fibHeap[T]{less: less}
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) GetMin() *T {
|
||||
return h.least.value
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) IsEmpty() bool { return h.least == nil }
|
||||
|
||||
func (h *fibHeap[T]) Insert(v *T) {
|
||||
ntree := &fibTree[T]{value: v}
|
||||
h.trees = append(h.trees, ntree)
|
||||
if h.least == nil || h.less(v, h.least.value) {
|
||||
h.least = ntree
|
||||
}
|
||||
h.count++
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) ExtractMin() *T {
|
||||
smallest := h.least
|
||||
if smallest != nil {
|
||||
// Remove smallest from root trees.
|
||||
for i := range h.trees {
|
||||
pos := h.trees[i]
|
||||
if pos == smallest {
|
||||
h.trees[i] = h.trees[len(h.trees)-1]
|
||||
h.trees = h.trees[:len(h.trees)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Add children to root
|
||||
h.trees = append(h.trees, smallest.child...)
|
||||
smallest.child = smallest.child[:0]
|
||||
|
||||
h.least = nil
|
||||
if len(h.trees) > 0 {
|
||||
h.consolidate()
|
||||
}
|
||||
|
||||
h.count--
|
||||
return smallest.value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) consolidate() {
|
||||
aux := make([]*fibTree[T], bits.Len(h.count)+1)
|
||||
for _, x := range h.trees {
|
||||
order := len(x.child)
|
||||
|
||||
// consolidate the larger roots under smaller roots of same order until we have at most one tree per order.
|
||||
for aux[order] != nil {
|
||||
y := aux[order]
|
||||
if h.less(y.value, x.value) {
|
||||
x, y = y, x
|
||||
}
|
||||
x.addAtEnd(y)
|
||||
aux[order] = nil
|
||||
order++
|
||||
}
|
||||
aux[order] = x
|
||||
}
|
||||
|
||||
h.trees = h.trees[:0]
|
||||
// move ordered trees to root and find least node.
|
||||
for _, k := range aux {
|
||||
if k != nil {
|
||||
k.parent = nil
|
||||
h.trees = append(h.trees, k)
|
||||
if h.least == nil || h.less(k.value, h.least.value) {
|
||||
h.least = k
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) Merge(a *fibHeap[T]) {
|
||||
h.trees = append(h.trees, a.trees...)
|
||||
h.count += a.count
|
||||
if h.least == nil || a.least != nil && h.less(a.least.value, h.least.value) {
|
||||
h.least = a.least
|
||||
}
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) find(fn func(*T) bool) *fibTree[T] {
|
||||
var st []*fibTree[T]
|
||||
st = append(st, h.trees...)
|
||||
var tr *fibTree[T]
|
||||
|
||||
for len(st) > 0 {
|
||||
tr, st = st[0], st[1:]
|
||||
ro := *tr.value
|
||||
if fn(&ro) {
|
||||
break
|
||||
}
|
||||
st = append(st, tr.child...)
|
||||
}
|
||||
|
||||
return tr
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) Find(fn func(*T) bool) *T {
|
||||
if needle := h.find(fn); needle != nil {
|
||||
return needle.value
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) DecreaseKey(find func(*T) bool, decrease func(*T)) {
|
||||
needle := h.find(find)
|
||||
if needle == nil {
|
||||
return
|
||||
}
|
||||
decrease(needle.value)
|
||||
|
||||
if h.less(needle.value, h.least.value) {
|
||||
h.least = needle
|
||||
}
|
||||
|
||||
if parent := needle.parent; parent != nil {
|
||||
if h.less(needle.value, parent.value) {
|
||||
h.cut(needle)
|
||||
h.cascadingCut(parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) cut(x *fibTree[T]) {
|
||||
parent := x.parent
|
||||
for i := range parent.child {
|
||||
pos := parent.child[i]
|
||||
if pos == x {
|
||||
parent.child[i] = parent.child[len(parent.child)-1]
|
||||
parent.child = parent.child[:len(parent.child)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
x.parent = nil
|
||||
x.mark = false
|
||||
h.trees = append(h.trees, x)
|
||||
|
||||
if h.less(x.value, h.least.value) {
|
||||
h.least = x
|
||||
}
|
||||
}
|
||||
|
||||
func (h *fibHeap[T]) cascadingCut(y *fibTree[T]) {
|
||||
if y.parent != nil {
|
||||
if !y.mark {
|
||||
y.mark = true
|
||||
return
|
||||
}
|
||||
|
||||
h.cut(y)
|
||||
h.cascadingCut(y.parent)
|
||||
}
|
||||
}
|
||||
|
||||
// FindPath uses the A* path finding algorithem.
|
||||
// g is the graph source that implements the pather interface.
|
||||
//
|
||||
// C is an numeric type for calculating cost/potential
|
||||
// N is the node values. is comparable for storing in visited table for pruning.
|
||||
//
|
||||
// start, end are nodes that dileniate the start and end of the search path.
|
||||
// The returned values are the calculated cost and the path taken from start to end.
|
||||
func FindPaths[C integer, N comparable](g pather[C, N], start, end N) ([]C, [][]N) {
|
||||
var zero C
|
||||
// closed := make(map[N]bool)
|
||||
|
||||
var potentialFn = func(N) C { var zero C; return zero }
|
||||
if p, ok := g.(interface{ Potential(N) C }); ok {
|
||||
potentialFn = p.Potential
|
||||
}
|
||||
|
||||
type node struct {
|
||||
cost C
|
||||
potential C
|
||||
parent *node
|
||||
position N
|
||||
closed map[N]bool
|
||||
}
|
||||
|
||||
NewPath := func(n *node) []N {
|
||||
var path []N
|
||||
for n.parent != nil {
|
||||
path = append(path, n.position)
|
||||
n = n.parent
|
||||
}
|
||||
path = append(path, n.position)
|
||||
|
||||
Reverse(path)
|
||||
return path
|
||||
}
|
||||
|
||||
less := func(b, a *node) bool {
|
||||
return b.cost+b.potential < a.cost+a.potential
|
||||
}
|
||||
|
||||
pq := PriorityQueue(less)
|
||||
pq.Insert(&node{position: start, closed: make(map[N]bool)})
|
||||
|
||||
defer func() {
|
||||
Log("queue max depth = ", pq.maxDepth, "total enqueue = ", pq.totalEnqueue, "total dequeue = ", pq.totalDequeue)
|
||||
}()
|
||||
|
||||
var seenFn = func(a N) N { return a }
|
||||
if s, ok := g.(interface{ Seen(N) N }); ok {
|
||||
seenFn = s.Seen
|
||||
}
|
||||
|
||||
var targetFn = func(n N, c C) bool { return true }
|
||||
if s, ok := g.(interface{ Target(N, C) bool }); ok {
|
||||
targetFn = s.Target
|
||||
}
|
||||
|
||||
var paths [][]N
|
||||
var costs []C
|
||||
|
||||
for !pq.IsEmpty() {
|
||||
current := pq.ExtractMin()
|
||||
cost, potential, n := current.cost, current.potential, current.position
|
||||
|
||||
seen := seenFn(n)
|
||||
if current.closed[seen] {
|
||||
continue
|
||||
}
|
||||
current.closed[seen] = true
|
||||
|
||||
if cost > 0 && potential == zero && cost > Max(0, costs...) && targetFn(current.position, cost) {
|
||||
paths = append([][]N(nil), NewPath(current))
|
||||
costs = append([]C(nil), cost)
|
||||
Log("new record = ", cost)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, nb := range g.Neighbors(n) {
|
||||
seen := seenFn(nb)
|
||||
if current.closed[seen] {
|
||||
continue
|
||||
}
|
||||
|
||||
cost := g.Cost(n, nb) + current.cost
|
||||
next := &node{
|
||||
position: nb,
|
||||
parent: current,
|
||||
cost: cost,
|
||||
potential: potentialFn(nb),
|
||||
closed: maps.Clone(current.closed),
|
||||
}
|
||||
// check if path is in open list
|
||||
if _, open := current.closed[seen]; !open {
|
||||
next.closed[seen] = false // add to open list
|
||||
pq.Insert(next)
|
||||
}
|
||||
}
|
||||
}
|
||||
return costs, paths
|
||||
}
|
||||
68
set.go
Normal file
68
set.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package aoc
|
||||
|
||||
import "golang.org/x/exp/maps"
|
||||
|
||||
type set[T comparable] map[T]struct{}
|
||||
|
||||
func Set[T comparable](arr ...T) set[T] {
|
||||
m := make(set[T], len(arr))
|
||||
for _, a := range arr {
|
||||
m[a] = struct{}{}
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *set[T]) Add(a T) {
|
||||
(*m)[a] = struct{}{}
|
||||
}
|
||||
func (m *set[T]) Items() []T {
|
||||
return maps.Keys(*m)
|
||||
}
|
||||
func (m *set[T]) Has(a T) bool {
|
||||
var ok bool
|
||||
_, ok = (*m)[a]
|
||||
return ok
|
||||
}
|
||||
|
||||
type defaultMap[K comparable, V any] struct {
|
||||
m map[K]V
|
||||
d V
|
||||
}
|
||||
|
||||
func DefaultMap[K comparable, V any](d V) *defaultMap[K, V] {
|
||||
return &defaultMap[K, V]{
|
||||
make(map[K]V),
|
||||
d,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultMap[K, V]) Set(k K, v V) {
|
||||
m.m[k] = v
|
||||
}
|
||||
func (m *defaultMap[K, V]) Get(k K) (V, bool) {
|
||||
if v, ok := m.m[k]; ok {
|
||||
return v, true
|
||||
}
|
||||
return m.d, false
|
||||
}
|
||||
|
||||
type pair[K, V any] struct {
|
||||
K K
|
||||
V V
|
||||
}
|
||||
|
||||
func (m *defaultMap[K, V]) Items() []pair[K, V] {
|
||||
var items = make([]pair[K, V], 0, len(m.m))
|
||||
for k, v := range m.m {
|
||||
items = append(items, pair[K, V]{k, v})
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func In[C comparable](n C, haystack ...C) bool {
|
||||
for _, h := range haystack {
|
||||
if n == h {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
27
set_test.go
Normal file
27
set_test.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package aoc_test
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/matryer/is"
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
)
|
||||
|
||||
func TestSet(t *testing.T) {
|
||||
is := is.New(t)
|
||||
|
||||
s := aoc.Set(1, 2, 3)
|
||||
is.True(!s.Has(0))
|
||||
is.True(s.Has(1))
|
||||
is.True(s.Has(2))
|
||||
is.True(s.Has(3))
|
||||
is.True(!s.Has(4))
|
||||
|
||||
s.Add(4)
|
||||
is.True(s.Has(4))
|
||||
|
||||
items := s.Items()
|
||||
sort.Ints(items)
|
||||
is.Equal(items, []int{1, 2, 3, 4})
|
||||
}
|
||||
0
template/example.txt
Normal file
0
template/example.txt
Normal file
0
template/input.txt
Normal file
0
template/input.txt
Normal file
30
template/main.go
Normal file
30
template/main.go
Normal file
@@ -0,0 +1,30 @@
|
||||
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) {
|
||||
|
||||
for scan.Scan() {
|
||||
_ = scan.Text()
|
||||
|
||||
}
|
||||
|
||||
return &result{}, nil
|
||||
}
|
||||
41
template/main_test.go
Normal file
41
template/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, 0)
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user