Merge branch 'main' into day07-enhance
Some checks failed
Go Test / build (pull_request) Failing after 37s
Some checks failed
Go Test / build (pull_request) Failing after 37s
This commit is contained in:
commit
c9e364af27
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 --race -cover ./...
|
||||
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
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
|
||||
|
||||
|
||||
*/
|
||||
|
|
54
day01/main_test.go
Normal file
54
day01/main_test.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,29 +3,19 @@ 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) {
|
||||
func run(scan *bufio.Scanner) (result, error) {
|
||||
var game1, game2 Game
|
||||
|
||||
for scan.Scan() {
|
||||
|
@ -50,7 +40,7 @@ func run(scan *bufio.Scanner) (uint64, uint64) {
|
|||
game2.wildCard = 'J'
|
||||
product2 := calcProduct(game2)
|
||||
|
||||
return product1, product2
|
||||
return result{product1, product2}, nil
|
||||
}
|
||||
|
||||
var cardTypes1 = []rune{'A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2'}
|
||||
|
|
|
@ -57,19 +57,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
|
||||
}
|
46
day14/main_test.go
Normal file
46
day14/main_test.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
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 @@
|
|||
\.......................\..........................................-..................-.../................-..
|
||||
....../.......\...-......-.|...\..............\.................|............././....-........................
|
||||
...............-...-........................................\......\..-.............|......-....\....-........
|
||||
..\..|.|...........................-.|........................................./.|....|................|......
|
||||
|../................|............................................................\........../..\..............
|
||||
........\............../................/..........................\...\....|............./....-.........\\...
|
||||
.................-...-...................\../........-|.................../......-...........|................
|
||||
........-............/...|-............-.....\.|..............-....-../\../..................\...\././........
|
||||
........................-|................................................................-........-..........
|
||||
-......./.................|.....\.................\.....//............-........./..../....|...................
|
||||
....-.............-........-..........-|.......|...../...\...................\.....................|..........
|
||||
...|...\.........|.................|.....|....-....\.......\./........................-.../..../.....-........
|
||||
....|....-.-..............\.........|.......................-.......-..............\................/.........
|
||||
.....|.\...........-.................-.-........../...\............|...............|...|......./.......|...../
|
||||
.....\.........................-.../..-./...\...................../......\...-.......|.\........-|............
|
||||
............|.....................................-....../....\.............../-...|...\..\................./.
|
||||
......-./|....../............|.........\............-../...-......./.\..\....../......|/...\..................
|
||||
................................|.......|..-..../.............................../.-..................-..-/..|.
|
||||
...............................-......./......................|./...............-............./....../........
|
||||
..................../....................\........\...........................-............/.../..............
|
||||
.|||......../.................|.................../..\............................-......./..|...|/.-.........
|
||||
......-......./\....../.........|....../.......-...............|.\........-............/.../..................
|
||||
.....................-.\/|................//.../.........|.|......\.-..|.........|.........\..................
|
||||
.........................\/.......|.|............................|........|.............................././..
|
||||
.................................|.................\../..|/.................\.................-...-........-/.
|
||||
......................-...-.........../...........................\....\......-..-.......\.-....\....|........
|
||||
......-......../..............\/..................\..|........-..............|...-...../......|...............
|
||||
|.......|.../....|..............//.....................|..........|/......../................|................
|
||||
...|.|..................../|..../.-.......-...........|.....|./....\......-......-................|...........
|
||||
......\/./.|\..../|.|..|..........-....|...........|.-.|...................-.\.....|....................\.....
|
||||
......../.\......................|.....|...........|.........../.......|....|...|.......-......../......\...-.
|
||||
...|...-...||......-..|..-...........|.-.................|.................................-..................
|
||||
..............-.\.-........|......\..........................................\./.\........../.....|...........
|
||||
../\.........|...............|............|.\/.-/.................-....|...-.................-.....|..../.....
|
||||
....................../......../..../-.....\........................\..-.\....|....-.........../-.............
|
||||
.................................|................|.........|................../|.....|....\\............/.\..
|
||||
...///./.....\.................|/.....................\...................-............|................|.....
|
||||
............-...........................--........\................/.............-\................\.....-.../
|
||||
...............\.........../|............................|.....................\...-...\.....................-
|
||||
...\.............|.............|................\............\|...../...|.........................|...........
|
||||
..................|......|..........-.-..............\.........................\..............................
|
||||
....-................../.........../...|................/...............|./.|.../....\..../......./......//...
|
||||
...../....../..............................|...\../..........-..........-........-..//..../...................
|
||||
...............-......|......................|./........./............/..-...........|../.....-........-./....
|
||||
..\.........................|...-.......\.................|..............-........\....-.............-....|...
|
||||
.......|......|....../........\...........|......-........../......-..................../....................\
|
||||
.......................|....-..|........./.|.-...............|..\......\.....-.......\...-/....|/.........\...
|
||||
\......\..-.....................\..........................\................................../...........\...
|
||||
-....-......../............................................................../.\.......|..............|....-..
|
||||
........|......................|.............-....\................................./..\.......|..........-...
|
||||
...-...............|........./......\...../.......|...|...............\.../...\.../......|.....-.\......\.....
|
||||
............./.....|......................|.....................................\...||.................-....|.
|
||||
./.....-................/........|./....-......../......./..............\..................................\..
|
||||
.../..../\........-..........................|.-/.|..\................\\-.......|......./...||.......|........
|
||||
.....-.........................-...............\...........|.............-.\.../.|......-.|......../...-.....-
|
||||
......\....................|...../......................|.../......-..|............|......./.../.........|....
|
||||
...|...........-....................................../.|............./....|..../........./.....\../..........
|
||||
....../.../................\........................\...\....\......\............../|...............\.-.......
|
||||
./....\.../.............|............................-.../............../............/...........\...|........
|
||||
............................|.................|/..........//.........../..-...............|...................
|
||||
.....\......\.................|.....|...\-./...............\................|....../.....-..\........-....-...
|
||||
........................./-........\................./........-/.|....-.......\............-/\......|.\...-...
|
||||
..../../..|.|...............\.......................................-.........................................
|
||||
...........|...................................................-...-......|..................\............../.
|
||||
/....|......................................................................|\.../.......-...........-...|....
|
||||
......|.-.\......-........|.....-..|.\..............-......./......-|.........................-...............
|
||||
............\......................................|........................|.-...............................
|
||||
.........-.........../....\./....../.-...-..//.........../.......\\...........................................
|
||||
........\......../............./...-......\.../..|..|............................../......../..\..............
|
||||
--.........|.....-...|............../...|.......|..............\|............|.........................|.-....
|
||||
-\......./..............-....-....\...|.-........\/.\./............-/...\........|-.........../../...\........
|
||||
.\|\..............-......-.\...-....\..........................\........|...........-......./.............../.
|
||||
..........................|...\..../.../..........\.............-...//...............\..................-.....
|
||||
........./..........................\............|-.....|..-...|......../........-...........................\
|
||||
.......\.../.....\....../.......|..|...............-......................|....-...................-.|........
|
||||
......|.......\.../..............................-..............................|......-.-...................\
|
||||
/.....|.......-............/|.....|-......./..../......-........../..|......../.-..\..../....../...|..........
|
||||
............/..--..........-............\.......\................\........................../../....|.........
|
||||
..|..-................|.|..|................/.......\............-//.......................\..\...............
|
||||
.......................-......-..................|....\................-......\.|....\....|..../../|.-........
|
||||
........................-..................-...........................-..-................-................|.
|
||||
/.\....|.-.................................\..-.....\./.........../-.|..............\..\.....--|/....\........
|
||||
.......-..-../..................\..--|..............|...............|\........|...--................|./.\.....
|
||||
..........|................-.......|..................................................|...................|...
|
||||
-.-..|....-.|........-./...|.-.........\.....\/........-........\........../................./.../........\...
|
||||
..................../...|/......................................../............\.|./../................/\|....
|
||||
...//.........................\....../..............\../.......-..\....|......................................
|
||||
............................./..|./../.........-/..\..........................................................
|
||||
......\.....|..................|..................\.....\.-..\...../............................../...........
|
||||
..........\...........-..........-.....-....\/................../.................................\.....|..\..
|
||||
..../.\...................................\............\...\....|.................|.....................-.....
|
||||
...........-...........................\.......|-../.|....|.....|......................-...../................
|
||||
.......|.........\..............|....\...-......../...........-.....-..-...........-..................\...\.|.
|
||||
...........|.......................|....-..........\............................\.................../.\.......
|
||||
..../.................\.......-..|.................../........................|...............\...........-.|.
|
||||
............./..|.-\..../.....-............-....|..\......|......../............-.........|................\..
|
||||
...................\...\/......\............|......................\....|...................-./-..............
|
||||
..-\...........|.................../.....|....|............................-..|............\.............\....
|
||||
.|.....\....\........|..................\...............|..-/.........|.-/...........-............-...........
|
||||
.....\...../......-............|........./..|............-........................\....-......................
|
||||
......\......../........|..............\...-..-...|.......................................................|...
|
||||
...................|.................................\.....\...........................|../.|.-......-........
|
||||
..................|..............\.....\............|........../....../...............\.........\.............
|
||||
..|...........-..../....\.........--...\................../.............-...-....................-..../....|..
|
||||
.|...\...................|......-...........-\..........\.....|.....|..........|.........|....|-../...........
|
||||
.............\|...................../\...............\....../.......-....\.....................-..............
|
||||
.......//.....................\....\......\......\.........|...................../......../.........\......-..
|
||||
.\./.........-...-./-.\.............../......|................................\|....\...../....-..............
|
||||
.......|......../......../......./.........../...............|............................../..|......../.....
|
||||
............./.........|.....-./.........../....-......./|......-................|............................
|
189
day16/main.go
Normal file
189
day16/main.go
Normal file
|
@ -0,0 +1,189 @@
|
|||
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)
|
||||
}
|
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)
|
||||
}
|
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=
|
||||
|
|
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)
|
||||
}
|
395
tools.go
Normal file
395
tools.go
Normal file
|
@ -0,0 +1,395 @@
|
|||
package aoc
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"cmp"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
input, err := os.Open(os.Args[1])
|
||||
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.Fprintln(os.Stderr, v...) }
|
||||
func Logf(format string, v ...any) {
|
||||
if !strings.HasSuffix(format, "\n") {
|
||||
format += "\n"
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, format, v...)
|
||||
}
|
||||
|
||||
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 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 ReadStringToInts(fields []string) []int {
|
||||
return SliceMap(Atoi, fields...)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 Sum[T integer](arr ...T) T {
|
||||
var acc T
|
||||
for _, a := range arr {
|
||||
acc += a
|
||||
}
|
||||
return acc
|
||||
}
|
||||
func SumFunc[T any, U integer](fn func(T) U, input ...T) U {
|
||||
return Sum(SliceMap(fn, input...)...)
|
||||
}
|
||||
func SumIFunc[T any, U integer](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 int) int {
|
||||
if i < 0 {
|
||||
return -i
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 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
|
||||
}
|
||||
|
||||
type PQElem[T any, I integer] struct {
|
||||
Value T
|
||||
Priority I
|
||||
}
|
||||
type PQList[T any, I integer] []PQElem[T, I]
|
||||
|
||||
func (pq PQList[T, I]) Len() int {
|
||||
return len(pq)
|
||||
}
|
||||
func (pq PQList[T, I]) Less(i int, j int) bool {
|
||||
return pq[i].Priority < pq[j].Priority
|
||||
}
|
||||
func (pq PQList[T, I]) Swap(i int, j int) {
|
||||
pq[i], pq[j] = pq[j], pq[i]
|
||||
}
|
||||
|
||||
var _ sort.Interface = (*PQList[rune, int])(nil)
|
||||
|
||||
type PriorityQueue[T any, I integer] struct {
|
||||
elem PQList[T, I]
|
||||
}
|
||||
|
||||
func (pq *PriorityQueue[T, I]) Enqueue(elem T, priority I) {
|
||||
pq.elem = append(pq.elem, PQElem[T, I]{elem, priority})
|
||||
sort.Sort(pq.elem)
|
||||
}
|
||||
func (pq *PriorityQueue[T, I]) IsEmpty() bool {
|
||||
return len(pq.elem) == 0
|
||||
}
|
||||
func (pq *PriorityQueue[T, I]) Dequeue() (T, bool) {
|
||||
var elem T
|
||||
if pq.IsEmpty() {
|
||||
return elem, false
|
||||
}
|
||||
|
||||
elem, pq.elem = pq.elem[0].Value, pq.elem[1:]
|
||||
return elem, true
|
||||
}
|
||||
|
||||
type Vertex[V comparable, I integer] struct {
|
||||
to V
|
||||
score I
|
||||
}
|
||||
type graph[V comparable, I uinteger] struct {
|
||||
adj map[V][]Vertex[V, I]
|
||||
}
|
||||
|
||||
func Graph[V comparable, I uinteger](size int) *graph[V, I] {
|
||||
return &graph[V, I]{
|
||||
adj: make(map[V][]Vertex[V, I], size),
|
||||
}
|
||||
}
|
||||
func (g *graph[V, I]) AddEdge(u, v V, w I) {
|
||||
g.adj[u] = append(g.adj[u], Vertex[V, I]{to: v, score: w})
|
||||
g.adj[v] = append(g.adj[v], Vertex[V, I]{to: u, score: w})
|
||||
}
|
||||
func (g *graph[V, I]) Dijkstra(m interface{Get()}, src V) map[V]I {
|
||||
pq := PriorityQueue[V, I]{}
|
||||
dist := make(map[V]I, len(g.adj))
|
||||
visited := make(map[V]bool, len(g.adj))
|
||||
var INF I
|
||||
INF = ^INF
|
||||
|
||||
pq.Enqueue(src, 0)
|
||||
dist[src] = 0
|
||||
|
||||
for !pq.IsEmpty() {
|
||||
u, _ := pq.Dequeue()
|
||||
|
||||
if _, ok := visited[u]; ok {
|
||||
continue
|
||||
}
|
||||
visited[u] = true
|
||||
|
||||
for _, v := range g.adj[u] {
|
||||
_, ok := visited[v.to]
|
||||
var du, dv I
|
||||
if d, inf := dist[u]; !inf {
|
||||
du = INF
|
||||
} else {
|
||||
du = d
|
||||
}
|
||||
if d, inf := dist[v.to]; !inf {
|
||||
dv = INF
|
||||
} else {
|
||||
dv = d
|
||||
}
|
||||
|
||||
if !ok && du+v.score < dv {
|
||||
dist[v.to] = du + v.score
|
||||
pq.Enqueue(v.to, du+v.score)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dist
|
||||
}
|
93
tools_test.go
Normal file
93
tools_test.go
Normal file
|
@ -0,0 +1,93 @@
|
|||
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 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 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 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)
|
||||
}
|
||||
|
||||
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},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
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 TestGraph(t *testing.T) {
|
||||
g := aoc.Graph[int, uint](7)
|
||||
g.AddEdge(0, 1, 2)
|
||||
g.AddEdge(0, 2, 6)
|
||||
g.AddEdge(1, 3, 5)
|
||||
g.AddEdge(2, 3, 8)
|
||||
g.AddEdge(3, 4, 10)
|
||||
g.AddEdge(3, 5, 15)
|
||||
g.AddEdge(4, 6, 2)
|
||||
g.AddEdge(5, 6, 6)
|
||||
// g.Dijkstra(0)
|
||||
}
|
Loading…
Reference in New Issue
Block a user