55 Commits

Author SHA1 Message Date
aa84e3974b feat: add day 6 2024
Some checks failed
Go Test / build (pull_request) Failing after 1m31s
2025-07-06 16:09:34 -06:00
xuu
aa0a2b7b7d feat: add day 5 2024
Some checks failed
Go Bump / bump (push) Failing after 44s
Go Test / build (push) Failing after 14m5s
2024-12-06 13:47:49 -07:00
xuu
77a0669f45 feat: add day 4 2024
Some checks failed
Go Bump / bump (push) Failing after 9s
Go Test / build (push) Failing after 54s
2024-12-06 11:28:30 -07:00
xuu
c077b91c41 fix(aoc2024): clean up day 3
Some checks failed
Go Bump / bump (push) Failing after 9s
Go Test / build (push) Failing after 52s
2024-12-04 08:24:59 -07:00
xuu
b3c36c1af1 Merge pull request 'AOC 2024 Day 3' (#23) from working2024D3 into main
Some checks failed
Go Bump / bump (push) Failing after 10s
Go Test / build (push) Failing after 57s
Reviewed-on: #23
2024-12-03 16:16:23 -07:00
xuu
6a17669107 feat(aoc2024): complete day 3 part 2
Some checks failed
Go Test / build (pull_request) Failing after 57s
2024-12-03 16:15:53 -07:00
xuu
127257c494 chore: state after where broken 2024-12-03 15:12:39 -07:00
xuu
7b9a71f84c chore: state before changes that were working 2024-12-03 15:11:33 -07:00
xuu
669e2cfb2c feat: add day 3 2024 (iter crashes on solution 2) 2024-12-03 14:51:54 -07:00
xuu
2274eca981 feat: add day 2 2024
Some checks failed
Go Bump / bump (push) Failing after 6s
Go Test / build (push) Failing after 44s
2024-12-02 10:24:38 -07:00
xuu
b1e4c4d634 feat: add day 1 2024
Some checks failed
Go Bump / bump (push) Failing after 8s
Go Test / build (push) Failing after 45s
2024-12-01 11:38:06 -07:00
xuu
4b3fc7eb73 chore: make reduce more iter.Seq 2024-12-01 11:37:27 -07:00
xuu
0d652660f1 chore: add day25 part 1
Some checks failed
Go Bump / bump (push) Failing after 6s
Go Test / build (push) Failing after 45s
2024-11-20 09:07:01 -07:00
xuu
e046a6c06d chore: cleanup and add tools 2024-10-30 13:32:44 -06:00
xuu
04bbac8559 chore: add hackerrank solutions
Some checks failed
Go Bump / bump (push) Failing after 6s
Go Test / build (push) Successful in 47s
2024-10-26 12:03:06 -06:00
xuu
3c9af95ec4 chore: setup folders for aoc 2024
Some checks failed
Go Bump / bump (push) Failing after 9s
Go Test / build (push) Successful in 38s
2024-10-26 11:38:44 -06:00
xuu
50af2114d4 add ranger
Some checks failed
Go Bump / bump (push) Failing after 6s
Go Test / build (push) Failing after 21s
2024-04-05 16:27:02 -06:00
xuu
f8fa61672f chore: fixes
All checks were successful
Go Bump / bump (push) Successful in 7s
Go Test / build (push) Successful in 35s
2024-01-22 16:07:16 -07:00
xuu
951c2c298a chore(aos): add compress graph
Some checks failed
Go Bump / bump (push) Successful in 9s
Go Test / build (push) Failing after 24s
2024-01-12 12:09:44 -07:00
xuu
328a0f3eb3 chore(aoc): add FibHeap DecreaseKey
All checks were successful
Go Bump / bump (push) Successful in 8s
Go Test / build (push) Successful in 40s
2024-01-09 20:41:23 -07:00
xuu
7d7402f054 chore(day17): implement fibHeap for faster priority queue
All checks were successful
Go Test / build (pull_request) Successful in 37s
Go Bump / bump (push) Successful in 7s
Go Test / build (push) Successful in 39s
2024-01-09 13:53:30 -07:00
xuu
7585526634 chore(day17): simplify FindPath. A* is still slower :|
Some checks failed
Go Test / build (pull_request) Failing after 4m27s
2024-01-04 17:15:44 -07:00
xuu
924c8d74f3 chore(day17): disable heuristic. runs faster!? 2024-01-02 20:57:02 -07:00
xuu
22184ed9c7 chore(aoc): initial graph attempt 2024-01-02 17:02:12 -07:00
xuu
74a952e82b chore(day19): add part 2
All checks were successful
Go Bump / bump (push) Successful in 6s
Go Test / build (push) Successful in 1m30s
2024-01-01 19:15:36 -07:00
xuu
62f8338227 chore: organization day19 2024-01-01 19:15:36 -07:00
xuu
39c6f8ed4d chore: add day 19 pt 1 2024-01-01 19:15:36 -07:00
xuu
2c959c109b tests(day17): disable solution
All checks were successful
Go Bump / bump (push) Successful in 7s
Go Test / build (push) Successful in 49s
2024-01-01 14:19:00 -07:00
xuu
eb1eaaab43 chore(day17): add open list for A*
Some checks failed
Go Bump / bump (push) Successful in 8s
Go Test / build (push) Failing after 4m29s
2024-01-01 14:12:53 -07:00
xuu
adc01f4df9 chore(day17): log output
All checks were successful
Go Bump / bump (push) Successful in 6s
Go Test / build (push) Successful in 40s
2024-01-01 12:44:08 -07:00
xuu
fd85530d88 chore(day17): simplify interfaces. add docs
All checks were successful
Go Bump / bump (push) Successful in 12s
Go Test / build (push) Successful in 46s
2024-01-01 10:59:40 -07:00
xuu
0d78959bea chore(day17): fix missing changes
All checks were successful
Go Test / build (pull_request) Successful in 37s
Go Bump / bump (push) Successful in 7s
Go Test / build (push) Successful in 34s
2024-01-01 09:57:08 -07:00
xuu
86f2f7a6f2 chore(day17): implent A* path finder
All checks were successful
Go Bump / bump (push) Successful in 8s
Go Test / build (pull_request) Successful in 51s
Go Test / build (push) Successful in 35s
2024-01-01 09:29:25 -07:00
xuu
378e403c1c Merge pull request 'chore: fix uncertanty on day17' (#18) from day17-enhance into main
All checks were successful
Go Bump / bump (push) Successful in 8s
Go Test / build (push) Successful in 34s
Reviewed-on: #18
2023-12-29 21:12:11 -07:00
xuu
06a22511b5 Merge branch 'main' into day17-enhance
All checks were successful
Go Test / build (pull_request) Successful in 36s
2023-12-29 21:11:24 -07:00
xuu
a2563b9d31 chore: fix uncertanty on day17
All checks were successful
Go Test / build (pull_request) Successful in 36s
2023-12-29 21:10:59 -07:00
xuu
3c2ea4ed9e Merge pull request 'chore: fix dijkstra' (#17) from day17-enhance into main
Some checks failed
Go Bump / bump (push) Failing after 8s
Go Test / build (push) Failing after 1m30s
Reviewed-on: #17
2023-12-28 19:01:39 -07:00
xuu
1fac5f7b4d chore: fix dijkstra
Some checks failed
Go Test / build (pull_request) Failing after 2m39s
2023-12-28 18:59:46 -07:00
xuu
1a3374a557 chore: save day18 (#12)
Some checks failed
Go Bump / bump (push) Successful in 7s
Go Test / build (push) Failing after 10m26s
Reviewed-on: #12
2023-12-27 14:07:32 -07:00
xuu
170fecc9f6 Merge pull request 'chore: add day 17 pt 2' (#16) from day17 into main
Some checks failed
Go Bump / bump (push) Successful in 21s
Go Test / build (push) Failing after 10m27s
Reviewed-on: #16
2023-12-26 13:30:31 -07:00
xuu
58e482b125 Merge branch 'main' into day17
Some checks failed
Go Test / build (pull_request) Failing after 10m28s
2023-12-26 13:30:25 -07:00
xuu
7847d11f95 chore: add day 17 pt 2
Some checks failed
Go Test / build (pull_request) Failing after 10m29s
2023-12-26 13:29:48 -07:00
xuu
d21005c534 Merge pull request 'chore: cleanup day 7' (#10) from day07-enhance into main
All checks were successful
Go Bump / bump (push) Successful in 6s
Go Test / build (push) Successful in 34s
Reviewed-on: #10
2023-12-26 13:18:08 -07:00
xuu
3e0ed68db3 Merge branch 'main' into day07-enhance
All checks were successful
Go Test / build (pull_request) Successful in 37s
2023-12-26 13:17:18 -07:00
xuu
f1ac3ea35f chore: fix day 07 2023-12-26 13:17:07 -07:00
xuu
f0696a6fe6 Merge pull request 'add day 20' (#13) from day20 into main
All checks were successful
Go Bump / bump (push) Successful in 11s
Go Test / build (push) Successful in 37s
Reviewed-on: #13
2023-12-26 13:03:00 -07:00
xuu
786a5bae35 Merge branch 'main' into day20
All checks were successful
Go Test / build (pull_request) Successful in 38s
2023-12-26 13:02:01 -07:00
xuu
e82c9a97c4 Merge pull request 'chore: add day 17 pt 2' (#14) from day17 into main
Some checks failed
Go Bump / bump (push) Successful in 10s
Go Test / build (push) Failing after 10m29s
Reviewed-on: #14
2023-12-26 12:44:04 -07:00
xuu
b2da6a35e7 Merge branch 'main' into day17
Some checks failed
Go Test / build (pull_request) Failing after 10m28s
2023-12-26 12:43:56 -07:00
xuu
970f5b2d76 chore: add day 17 pt 2
Some checks failed
Go Test / build (pull_request) Failing after 10m27s
2023-12-26 12:42:11 -07:00
xuu
8e451050b1 Merge branch 'main' into day20
Some checks failed
Go Test / build (pull_request) Failing after 43s
2023-12-21 17:04:25 -07:00
xuu
761013df81 chore: cleanup day 20
All checks were successful
Go Test / build (pull_request) Successful in 34s
2023-12-21 16:44:35 -07:00
xuu
eb9e770a94 chore: add day20 2023-12-21 13:18:59 -07:00
xuu
13888edaff chore: start day20 2023-12-20 11:27:54 -07:00
xuu
50f1016372 chore: cleanup 2023-12-08 12:11:44 -07:00
158 changed files with 12187 additions and 746 deletions

View File

@@ -28,6 +28,6 @@ jobs:
go-version: 1.21.3 go-version: 1.21.3
- name: Test - name: Test
run: go test --race -cover ./... run: go test -timeout 240s -race -cover ./...
- run: echo "🍏 This job's status is ${{ job.status }}." - run: echo "🍏 This job's status is ${{ job.status }}."

6
README.md.sig Normal file
View File

@@ -0,0 +1,6 @@
-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgZ+OuJYdd3UiUbyBuO1RlsQR20a
Qm5mKneuMxRjGo3zkAAAAEZmlsZQAAAAAAAAAGc2hhNTEyAAAAUwAAAAtzc2gtZWQyNTUx
OQAAAED8T4C6WILXYZ1KxqDIlVhlrAEjr1Vc+tn8ypcVM3bN7iOexVvuUuvm90nr8eEwKU
acrdDxmq2S+oysQbK+pMUE
-----END SSH SIGNATURE-----

View File

@@ -30,7 +30,6 @@ func TestExample1(t *testing.T) {
is.Equal(result.sum, 142) is.Equal(result.sum, 142)
} }
func TestExample2(t *testing.T) { func TestExample2(t *testing.T) {
is := is.New(t) is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(example2)) scan := bufio.NewScanner(bytes.NewReader(example2))

1000
aoc2023/day07/input2.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@ import (
"bufio" "bufio"
_ "embed" _ "embed"
"fmt" "fmt"
"slices"
"strings" "strings"
aoc "go.sour.is/advent-of-code" aoc "go.sour.is/advent-of-code"
@@ -62,7 +63,7 @@ func run(scan *bufio.Scanner) (*result, error) {
func(i int, v int, counts [3]int) [3]int { func(i int, v int, counts [3]int) [3]int {
counts[v]++ counts[v]++
return counts return counts
}, [3]int{}, maps.Values(memo)...) }, [3]int{}, slices.Values(maps.Values(memo)))
// fmt.Println(i, counts) // fmt.Println(i, counts)
i = 1_000_000_000 - (1_000_000_000-counts[0]-counts[1])%counts[2] i = 1_000_000_000 - (1_000_000_000-counts[0]-counts[1])%counts[2]

View File

@@ -36,11 +36,10 @@ func TestSolution(t *testing.T) {
is.NoErr(err) is.NoErr(err)
t.Log(result) t.Log(result)
is.True(result.valuePT2 < 87286) // first submission is.True(result.valuePT2 < 87286) // first submission
is.True(result.valuePT2 < 87292) // second submission is.True(result.valuePT2 < 87292) // second submission
is.True(result.valuePT2 < 87287) // third submission is.True(result.valuePT2 < 87287) // third submission
is.Equal(result.valuePT1, 110407) is.Equal(result.valuePT1, 110407)
is.Equal(result.valuePT2, 87273) is.Equal(result.valuePT2, 87273)
} }

View File

@@ -32,14 +32,14 @@ func run(scan *bufio.Scanner) (*result, error) {
r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int { r.valuePT1 = aoc.Reduce(func(i int, t string, sum int) int {
sum += hash(t) sum += hash(t)
return sum return sum
}, 0, ops...) }, 0, slices.Values(ops))
} }
var boxen boxes var boxen boxes
boxen = aoc.Reduce(func(i int, op string, b boxes) boxes { boxen = aoc.Reduce(func(i int, op string, b boxes) boxes {
return b.Op(op) return b.Op(op)
}, boxen, ops...) }, boxen, slices.Values(ops))
r.valuePT2 = boxen.Sum() r.valuePT2 = boxen.Sum()

View File

@@ -32,15 +32,15 @@ func run(scan *bufio.Scanner) (*result, error) {
options := make([]int, 2*(rows+cols)+2) options := make([]int, 2*(rows+cols)+2)
i := 0 i := 0
for j:=0; j<=rows-1; j++ { for j := 0; j <= rows-1; j++ {
options[i+0] = runCycle(m, ray{[2]int{j, -1}, RT}) options[i+0] = runCycle(m, ray{[2]int{j, -1}, RT})
options[i+1] = runCycle(m, ray{[2]int{j, cols}, LF}) options[i+1] = runCycle(m, ray{[2]int{j, cols}, LF})
i+=2 i += 2
} }
for j:=0; j<=cols-1; j++ { for j := 0; j <= cols-1; j++ {
options[i+0] = runCycle(m, ray{[2]int{-1, j}, DN}) options[i+0] = runCycle(m, ray{[2]int{-1, j}, DN})
options[i+1] = runCycle(m, ray{[2]int{rows, j}, UP}) options[i+1] = runCycle(m, ray{[2]int{rows, j}, UP})
i+=2 i += 2
} }
// fmt.Println(options) // fmt.Println(options)
@@ -96,7 +96,6 @@ func (m *Map) Get(p [2]int) rune {
return (*m)[p[0]][p[1]] return (*m)[p[0]][p[1]]
} }
func runCycle(m Map, r ray) int { func runCycle(m Map, r ray) int {
current := r current := r
@@ -186,4 +185,4 @@ func runCycle(m Map, r ray) int {
// } // }
return len(energized) return len(energized)
} }

View File

@@ -47,4 +47,4 @@ func TestStack(t *testing.T) {
s := stack[int]{} s := stack[int]{}
s.Push(5) s.Push(5)
is.Equal(s.Pop(), 5) is.Equal(s.Pop(), 5)
} }

225
aoc2023/day17/main.go Normal file
View File

@@ -0,0 +1,225 @@
package main
import (
"bufio"
_ "embed"
"fmt"
aoc "go.sour.is/advent-of-code"
)
var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(run)) }
type result struct {
valuePT1 int
valuePT2 int
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(scan *bufio.Scanner) (*result, error) {
var m aoc.Map[int16, rune]
for scan.Scan() {
text := scan.Text()
m = append(m, []rune(text))
}
log("start day 17")
result := result{}
result.valuePT1 = search(m, 1, 3, seenFn)
log("result from part 1 = ", result.valuePT1)
result.valuePT2 = search(m, 4, 10, nil)
log("result from part 2 = ", result.valuePT2)
return &result, nil
}
type Point = aoc.Point[int16]
type Map = aoc.Map[int16, rune]
// rotate for changing direction
type rotate int8
const (
CW rotate = 1
CCW rotate = -1
)
// diretion of path steps
type direction int8
var (
U = Point{-1, 0}
R = Point{0, 1}
D = Point{1, 0}
L = Point{0, -1}
)
var directions = []Point{U, R, D, L}
var directionIDX = func() map[Point]direction {
m := make(map[Point]direction, len(directions))
for k, v := range directions {
m[v] = direction(k)
}
return m
}()
// position on the map
type position struct {
loc Point
direction Point
steps int8
}
func (p position) step() position {
return position{p.loc.Add(p.direction), p.direction, p.steps + 1}
}
func (p position) rotateAndStep(towards rotate) position {
d := directions[(int8(directionIDX[p.direction])+int8(towards)+4)%4]
return position{p.loc.Add(d), d, 1}
}
// implements FindPath graph interface
type graph struct {
min, max int8
m Map
target Point
reads int
seenFn func(a position) position
}
// Neighbors returns valid steps from given position. if at target returns none.
func (g *graph) Neighbors(current position) []position {
var nbs []position
if current.steps == 0 {
return []position{
{R, R, 1},
{D, D, 1},
}
}
if current.loc == g.target {
return nil
}
if left := current.rotateAndStep(CCW); current.steps >= g.min && g.m.Valid(left.loc) {
nbs = append(nbs, left)
}
if right := current.rotateAndStep(CW); current.steps >= g.min && g.m.Valid(right.loc) {
nbs = append(nbs, right)
}
if forward := current.step(); current.steps < g.max && g.m.Valid(forward.loc) {
nbs = append(nbs, forward)
}
return nbs
}
// Cost calculates heat cost to neighbor from map
func (g *graph) Cost(a, b position) int16 {
g.reads++
_, r, _ := g.m.Get(b.loc)
return int16(r - '0')
}
// Potential calculates distance to target
// func (g *graph) Potential(a position) int16 {
// return aoc.ManhattanDistance(a.loc, g.target)
// }
// Target returns true when target reached. receives node and cost.
func (g *graph) Target(a position, c int16) bool {
if a.loc == g.target && a.steps >= g.min && a.steps <= g.max {
return true
}
return false
}
// Seen attempt at simplifying the seen to use horizontal/vertical and no steps.
// It returns correct for part1 but not part 2..
func (g *graph) Seen(a position) position {
if g.seenFn != nil {
return g.seenFn(a)
}
return a
}
func seenFn(a position) position {
if a.direction == U {
a.direction = D
}
if a.direction == L {
a.direction = R
}
// a.steps = 0
return a
}
func search(m Map, minSteps, maxSteps int8, seenFn func(position) position) int {
rows, cols := m.Size()
start := Point{}
target := Point{rows - 1, cols - 1}
g := graph{min: minSteps, max: maxSteps, m: m, target: target, seenFn: seenFn}
cost, path, closed := aoc.FindPath[int16, position](&g, position{loc: start}, position{loc: target})
log("total map reads = ", g.reads, "cost = ", cost)
printGraph(m, path, closed, g.seenFn)
return int(cost)
}
// printGraph with the path/cost overlay
func printGraph(m Map, path []position, closed map[position]int16, seenFn func(a position) position) {
pts := make(map[Point]position, len(path))
for _, pt := range path {
pts[pt.loc] = pt
}
clpt := make(map[position]position, len(closed))
for pt := range closed {
clpt[position{loc: pt.loc, steps: pt.steps}] = pt
}
for r, row := range m {
// if r == 0 {
// for c := range row {
// if c == 0 {
// fmt.Print(" ")
// }
// fmt.Printf("% 5d", c)
// }
// fmt.Println("")
// }
for c := range row {
// if c == 0 {
// fmt.Printf("% 5d", r)
// }
if pt, ok := pts[Point{int16(r), int16(c)}]; ok {
if seenFn != nil {
pt = seenFn(pt)
}
_ = pt
// fmt.Printf("% 5d", closed[pt])
fmt.Print("*")
continue
}
// fmt.Print(" ....")
fmt.Print(" ")
}
fmt.Println("")
}
fmt.Println("")
}

View File

@@ -0,0 +1,41 @@
package main
import (
"bufio"
"bytes"
"testing"
_ "embed"
"github.com/matryer/is"
)
//go:embed example.txt
var example []byte
//go:embed input.txt
var input []byte
func TestExample(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(example))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 102)
is.Equal(result.valuePT2, 94)
}
func TestSolution(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(input))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 843)
is.Equal(result.valuePT2, 1017)
}

14
aoc2023/day18/example.txt Normal file
View File

@@ -0,0 +1,14 @@
R 6 (#70c710)
D 5 (#0dc571)
L 2 (#5713f0)
D 2 (#d2c081)
R 2 (#59c680)
D 2 (#411b91)
L 5 (#8ceee2)
U 2 (#caa173)
L 1 (#1b58a2)
U 2 (#caa171)
R 2 (#7807d2)
U 3 (#a77fa3)
L 2 (#015232)
U 2 (#7a21e3)

766
aoc2023/day18/input.txt Normal file
View File

@@ -0,0 +1,766 @@
R 4 (#0a7a60)
U 8 (#4453b3)
R 6 (#8e4f70)
U 2 (#4453b1)
R 4 (#0feb00)
U 4 (#355591)
R 8 (#2a09c0)
U 4 (#544c71)
R 4 (#472930)
U 2 (#199e33)
R 3 (#3d8df0)
U 5 (#199e31)
R 7 (#45de50)
U 4 (#57a941)
L 7 (#671c70)
U 5 (#5e5e81)
R 4 (#2e9b60)
U 8 (#490881)
L 7 (#1846f0)
U 3 (#304101)
L 4 (#1846f2)
D 2 (#58f3f1)
L 9 (#2e9b62)
D 2 (#56dcd1)
L 2 (#671c72)
D 9 (#275fd1)
L 4 (#76b7b2)
U 9 (#5b9641)
L 4 (#1d3212)
U 10 (#3d1841)
L 3 (#5ad5e2)
D 6 (#010211)
L 5 (#13ec52)
D 8 (#166471)
L 3 (#53ebc0)
D 5 (#0fdba1)
L 4 (#54e450)
D 9 (#440a21)
L 3 (#49b242)
D 5 (#2f0171)
L 6 (#447332)
D 4 (#182561)
L 8 (#1aaaa2)
D 6 (#0996a1)
L 4 (#1c1212)
D 6 (#5780d1)
L 7 (#0fc1d2)
D 7 (#36cb41)
L 3 (#505552)
D 7 (#8d8b81)
R 4 (#2bf742)
D 7 (#152791)
R 5 (#760492)
D 3 (#11a991)
R 3 (#5debc0)
D 10 (#59f211)
L 4 (#66d342)
D 8 (#1fc6b1)
R 4 (#66d340)
D 6 (#72dff1)
L 2 (#3f1b10)
D 4 (#2fca13)
L 10 (#2d0162)
D 5 (#8b5e53)
L 6 (#2d0160)
U 2 (#317053)
L 2 (#650c20)
U 7 (#2bed01)
R 10 (#409ed0)
U 2 (#166713)
L 10 (#939350)
U 6 (#166711)
L 4 (#38a180)
D 3 (#1d95f1)
L 6 (#11ea60)
D 5 (#931dc1)
R 6 (#11bf70)
D 7 (#536051)
L 3 (#995b60)
D 2 (#254e91)
L 3 (#332fd2)
U 6 (#7669f1)
L 3 (#574642)
U 6 (#1778a1)
L 3 (#1a00c2)
U 5 (#2eaa81)
L 3 (#1cf8e2)
U 6 (#0c71a1)
L 6 (#868472)
U 3 (#0a9fd1)
R 9 (#104c02)
U 4 (#082451)
L 7 (#850d02)
U 6 (#082453)
L 7 (#322552)
U 3 (#1339d1)
L 6 (#8e11d2)
U 4 (#6c5691)
R 6 (#1dda10)
U 3 (#25e5c3)
R 7 (#370670)
U 4 (#9324f1)
L 3 (#451030)
U 7 (#1f1021)
L 7 (#0ba3c0)
U 5 (#8a10a3)
L 8 (#67db30)
U 5 (#282473)
L 4 (#0cd350)
U 4 (#25e5c1)
R 3 (#6b4ee0)
U 4 (#333cf1)
R 5 (#02b610)
D 4 (#4e7cc1)
R 3 (#92abb0)
U 5 (#2f6ff1)
R 5 (#483360)
U 5 (#7b1cd1)
L 8 (#3a5d50)
U 3 (#1d2461)
R 8 (#3b2fd0)
U 5 (#630763)
R 6 (#5033c0)
U 3 (#252523)
R 7 (#08eeb0)
U 8 (#516633)
L 7 (#156240)
U 4 (#2db063)
L 3 (#791070)
D 5 (#2920a3)
L 3 (#0dafe0)
U 5 (#4185b3)
L 5 (#7ac0e0)
U 2 (#5a6cd3)
L 2 (#3ca790)
U 7 (#755403)
L 4 (#3b0740)
U 5 (#2004a3)
L 3 (#2db4f0)
U 6 (#602a23)
R 5 (#32c1c0)
D 2 (#000f53)
R 5 (#388360)
D 7 (#24d9e3)
R 4 (#4703a0)
D 3 (#2f1133)
R 3 (#4703a2)
U 11 (#52e853)
R 5 (#278132)
D 11 (#0665e3)
R 3 (#239112)
U 6 (#8f0ad1)
R 5 (#447de2)
U 6 (#8f0ad3)
R 6 (#636122)
U 2 (#187283)
R 3 (#5aae62)
U 10 (#1d8833)
L 5 (#476db0)
U 5 (#136393)
L 7 (#29e6b0)
U 5 (#136391)
R 7 (#3ba060)
U 3 (#635e23)
L 5 (#2042f0)
U 3 (#181643)
L 6 (#5af952)
U 8 (#28d0b1)
L 2 (#4a98f2)
U 9 (#28d0b3)
L 6 (#27a572)
D 3 (#3d7213)
L 4 (#516842)
D 11 (#21ef63)
L 5 (#38e342)
D 2 (#1118b3)
L 3 (#560502)
D 9 (#1118b1)
R 2 (#1c39a2)
D 2 (#303ab3)
R 6 (#716ba0)
D 6 (#780a93)
L 8 (#77ec30)
U 2 (#780a91)
L 3 (#271100)
U 10 (#5882f3)
L 4 (#2050c2)
D 3 (#434843)
L 3 (#7d9572)
D 2 (#3129b3)
L 5 (#21fb12)
D 5 (#8c2c33)
L 4 (#57bf92)
D 6 (#2730b3)
L 4 (#6a3902)
D 8 (#4656a3)
L 5 (#60ac80)
D 4 (#43b863)
R 9 (#3d69a0)
D 8 (#3ca913)
L 2 (#411d80)
D 3 (#725383)
L 8 (#4a98d0)
D 9 (#274553)
L 5 (#580d60)
U 5 (#568223)
L 6 (#473af0)
U 5 (#827593)
L 7 (#251dc2)
U 5 (#0fcea3)
L 8 (#5ae3d2)
U 3 (#4efa11)
R 9 (#389852)
U 2 (#7f7f91)
R 6 (#618342)
U 3 (#441143)
L 7 (#886df2)
U 3 (#26a093)
L 8 (#886df0)
U 4 (#63c7d3)
L 3 (#04f842)
D 10 (#0fcea1)
L 6 (#388e62)
U 10 (#3ae7f3)
L 3 (#2a6880)
U 6 (#3bfd53)
L 6 (#73a0c0)
U 5 (#3bfd51)
L 4 (#0d18a0)
U 2 (#19da93)
L 6 (#120600)
U 8 (#233b53)
L 6 (#2e1050)
U 3 (#4b2aa3)
L 4 (#5f9930)
U 10 (#6e65f1)
R 6 (#1eefa0)
U 9 (#50b9d3)
R 2 (#548ed0)
U 9 (#50b9d1)
R 7 (#8bd9f0)
U 4 (#5ae473)
R 6 (#0b0490)
U 10 (#186891)
R 4 (#764830)
U 7 (#33b0e1)
R 5 (#363c90)
U 8 (#7bd631)
R 7 (#031e30)
U 7 (#095881)
R 3 (#640e50)
D 5 (#02e7f3)
R 7 (#0922f0)
D 7 (#6b7af3)
R 9 (#0922f2)
D 3 (#62e543)
R 3 (#21e320)
U 9 (#5ead81)
R 7 (#01fd70)
D 9 (#3b0cf1)
R 2 (#2758a0)
D 5 (#7279b1)
R 8 (#5c7dc0)
D 7 (#3c8db1)
R 4 (#3c3740)
U 2 (#26b151)
R 6 (#11eb12)
U 4 (#587921)
R 6 (#11eb10)
U 4 (#320051)
R 4 (#038630)
U 3 (#6a2e61)
R 2 (#4ff680)
U 5 (#3c57f1)
R 9 (#0b2440)
U 8 (#497533)
L 6 (#704680)
U 11 (#549113)
R 6 (#23b470)
U 4 (#9e0641)
R 7 (#1aeec0)
D 7 (#4a6331)
R 2 (#547d80)
D 5 (#457a71)
R 9 (#7daa90)
D 4 (#16d7b1)
L 6 (#266810)
D 3 (#363561)
L 5 (#5312b2)
D 4 (#42c301)
R 5 (#9a0952)
D 7 (#42c303)
R 7 (#7d1df2)
D 4 (#51e321)
R 5 (#609422)
D 4 (#3b8f01)
R 6 (#644792)
U 4 (#2d8b11)
R 7 (#22bbc2)
D 7 (#6b39b1)
R 5 (#680e72)
U 2 (#7f9f31)
R 3 (#0e9b52)
U 3 (#3086c1)
R 3 (#5a60c0)
U 6 (#53b6e3)
R 7 (#8117d0)
U 7 (#53b6e1)
R 3 (#2cb930)
U 3 (#1bffd1)
R 6 (#4539f0)
U 8 (#680411)
R 4 (#6032c0)
U 6 (#255061)
R 3 (#5562a0)
U 6 (#088071)
R 3 (#3bf2f0)
U 5 (#52bdb1)
L 6 (#070500)
U 5 (#69e001)
R 6 (#070502)
U 3 (#071051)
R 2 (#036000)
U 4 (#0ea8a1)
R 5 (#05e4d0)
U 3 (#674de1)
R 3 (#804250)
D 6 (#3ffca1)
R 4 (#23dcb2)
D 6 (#9f9841)
L 5 (#45f210)
D 9 (#15efc1)
R 5 (#45f212)
D 4 (#969551)
L 9 (#23dcb0)
D 2 (#41bea1)
L 4 (#2f2a32)
D 4 (#71ffd1)
R 3 (#5c0bb2)
D 7 (#6f3501)
R 4 (#2b0a72)
D 4 (#7b3571)
R 3 (#1c67d2)
U 11 (#42f011)
R 3 (#51ae62)
D 3 (#75fcf1)
R 3 (#1f4742)
D 4 (#2813f1)
R 4 (#3d1812)
D 2 (#2b1d01)
R 11 (#1eb302)
U 3 (#27b0a1)
R 4 (#227b20)
U 5 (#34b7e1)
R 10 (#201220)
U 7 (#0502f3)
R 4 (#5ab7f0)
U 4 (#0502f1)
R 4 (#5d09b0)
U 7 (#504a81)
R 7 (#1e8250)
U 3 (#715aa1)
R 6 (#26d290)
U 6 (#9a12f1)
L 3 (#18be90)
U 8 (#037d11)
L 5 (#647600)
U 3 (#40b983)
L 5 (#04e450)
U 3 (#9a9a43)
L 8 (#04e452)
U 6 (#8af153)
R 8 (#6cbc90)
U 4 (#04d121)
L 4 (#285292)
U 3 (#688d51)
L 6 (#176332)
U 4 (#400a91)
L 5 (#176330)
U 5 (#43def1)
R 2 (#285290)
U 2 (#3e0711)
R 3 (#7eb9c0)
U 7 (#36f611)
R 7 (#666af0)
D 7 (#381b31)
R 3 (#298922)
U 3 (#475671)
R 6 (#977c12)
D 4 (#602d01)
R 6 (#25b0c2)
D 6 (#7ede81)
R 3 (#1d58c2)
D 8 (#873523)
L 9 (#265ae2)
D 3 (#57d663)
R 7 (#1565c2)
D 8 (#06ed11)
R 4 (#a348c2)
D 2 (#06ed13)
R 8 (#12d052)
D 4 (#2d3741)
L 7 (#0ccfd2)
D 3 (#1fcd61)
R 4 (#39a4c2)
D 3 (#44f7f1)
R 6 (#5c3202)
D 8 (#2625c1)
L 8 (#2b08c2)
D 2 (#20d7e1)
L 2 (#67b892)
D 10 (#546471)
R 7 (#484ef2)
D 7 (#49bc91)
R 4 (#91aa72)
U 11 (#499591)
R 3 (#0048b2)
U 7 (#34a7a1)
R 7 (#514600)
U 8 (#1cdc43)
L 7 (#471470)
U 3 (#8c8393)
R 3 (#18a780)
U 5 (#8c8391)
R 3 (#4e6f80)
U 3 (#1cdc41)
R 8 (#428930)
U 5 (#5dcb51)
R 3 (#4b21e2)
U 4 (#0464b1)
R 9 (#850552)
D 8 (#464881)
R 7 (#543852)
D 3 (#2d3a11)
R 3 (#081b22)
D 5 (#0cc731)
R 7 (#6990e0)
D 3 (#79d7b1)
R 3 (#509520)
D 5 (#438571)
R 3 (#27d510)
D 3 (#30d2d3)
L 8 (#1b7a00)
D 5 (#8a0da3)
L 8 (#1b7a02)
U 5 (#027cb3)
L 7 (#350130)
D 8 (#2ff771)
R 7 (#16dc02)
D 2 (#68f1c1)
R 5 (#02f782)
D 6 (#4e2a41)
R 11 (#448e32)
D 5 (#2cfac1)
L 11 (#417502)
D 5 (#2cfac3)
L 4 (#22f022)
U 9 (#1e9f01)
L 5 (#543572)
U 3 (#076e31)
L 6 (#081b20)
U 5 (#1ae851)
L 3 (#823132)
U 9 (#2d7993)
L 4 (#5738f2)
D 8 (#79e273)
L 4 (#5c9ad2)
D 8 (#4ed1b3)
L 3 (#311722)
D 4 (#0d5493)
L 6 (#5d63e0)
D 6 (#178cf3)
L 5 (#75b1b0)
D 5 (#178cf1)
L 6 (#11d550)
D 6 (#44ed03)
L 3 (#76a842)
U 6 (#3b6993)
L 5 (#184892)
D 4 (#5c8163)
L 3 (#14d872)
U 2 (#261a01)
L 5 (#2d01e2)
U 9 (#326ca3)
L 4 (#59ad32)
U 8 (#326ca1)
R 4 (#389ab2)
U 9 (#261a03)
L 4 (#50cb42)
D 4 (#2f8263)
L 5 (#9f3752)
D 6 (#4bb383)
L 4 (#2693f2)
D 4 (#19dca3)
R 4 (#475bc2)
D 6 (#960e13)
L 7 (#0c90a2)
D 8 (#3463d3)
L 6 (#5a82e2)
D 3 (#5a5c43)
R 7 (#120bf2)
D 3 (#5069e3)
R 3 (#4b47a2)
D 6 (#635b63)
R 4 (#66ca10)
U 4 (#1418f1)
R 7 (#1d5470)
D 4 (#1418f3)
R 8 (#66d4f0)
D 5 (#3c5533)
R 4 (#2f6e02)
D 3 (#2cf5e3)
R 4 (#633ec2)
D 7 (#2cf5e1)
R 7 (#5846b2)
D 3 (#4f9d63)
R 4 (#533380)
D 11 (#13c7e3)
R 2 (#222b62)
D 3 (#928ab3)
R 5 (#222b60)
U 5 (#0a4793)
R 5 (#15d3b0)
U 8 (#363fe1)
R 4 (#2feb30)
U 5 (#05d8b1)
R 3 (#39e030)
U 3 (#05d8b3)
R 2 (#3cd780)
U 8 (#02c781)
R 5 (#186452)
D 3 (#37bba1)
R 5 (#9e1232)
D 5 (#58e6f1)
R 5 (#182c30)
D 5 (#072db1)
R 5 (#85e600)
D 4 (#607651)
R 5 (#186450)
D 3 (#0aca91)
L 5 (#0ceb10)
D 5 (#860001)
L 6 (#54c8b0)
U 5 (#393971)
L 4 (#37c390)
D 3 (#1f1433)
L 5 (#3d8790)
D 6 (#353623)
R 4 (#78c830)
D 4 (#6fafa3)
R 6 (#2b0612)
D 5 (#31fff3)
R 7 (#8b49b2)
D 9 (#6f0ee3)
R 5 (#4212e0)
D 6 (#5d11f3)
R 6 (#648340)
D 8 (#393743)
R 6 (#34ddd0)
U 8 (#346fb3)
R 5 (#34fc22)
D 4 (#71c453)
R 6 (#5048f2)
D 4 (#0bb993)
R 4 (#42b9f0)
D 9 (#5cdf83)
R 5 (#42b9f2)
D 3 (#6f3f93)
R 3 (#3dbae2)
D 8 (#495363)
R 9 (#328ba2)
D 3 (#77afa1)
R 5 (#575710)
D 2 (#10d861)
R 4 (#257822)
D 4 (#6efe61)
R 9 (#257820)
D 5 (#521d01)
R 5 (#575712)
D 6 (#494cf1)
L 5 (#683ab2)
D 4 (#5e79c3)
L 3 (#4242a2)
D 4 (#5e79c1)
L 7 (#2c3442)
D 8 (#2fbd23)
L 5 (#636fb2)
D 5 (#63bd53)
L 2 (#299960)
D 6 (#31ea33)
R 3 (#51dfb0)
D 7 (#4e4ec3)
R 4 (#7b7912)
D 5 (#4b4bf3)
R 4 (#54e882)
D 5 (#7d2193)
R 3 (#3b77d2)
D 3 (#826973)
R 8 (#646ec2)
D 4 (#076c63)
L 10 (#674052)
D 6 (#3676b1)
L 9 (#3bd890)
D 4 (#7feb71)
L 3 (#3bd892)
D 3 (#27fc21)
R 8 (#66bba2)
D 8 (#645c73)
R 5 (#43e132)
D 5 (#51d9e3)
R 8 (#43e130)
D 6 (#2827f3)
R 4 (#412c92)
D 5 (#7e7f63)
L 4 (#218122)
D 4 (#546e83)
L 9 (#82f672)
D 8 (#6ed383)
L 3 (#701412)
D 7 (#47de23)
L 5 (#46f912)
D 7 (#0d9ec3)
L 4 (#515142)
D 3 (#4699e3)
L 9 (#2ed562)
U 6 (#00a273)
L 9 (#8d7d12)
U 2 (#6c3a83)
L 7 (#318fa2)
U 7 (#0bd473)
L 2 (#6d5050)
U 10 (#415673)
R 3 (#9e8420)
U 6 (#1ff213)
R 5 (#0c8bf0)
U 2 (#479a11)
R 6 (#977360)
U 5 (#479a13)
L 8 (#250680)
U 2 (#1ff211)
L 3 (#216630)
U 3 (#22d143)
L 3 (#3b4342)
U 7 (#9d4ff3)
L 5 (#43aca2)
U 6 (#29efd3)
L 3 (#5c6a12)
D 11 (#134a73)
L 6 (#2a0982)
U 11 (#444723)
L 4 (#47e2e2)
U 4 (#6855c3)
L 4 (#06a382)
U 4 (#2222e3)
R 3 (#4edc62)
U 6 (#9a2683)
R 6 (#131872)
U 10 (#4f5a23)
R 4 (#858f70)
U 5 (#4d4823)
L 9 (#3f73f0)
U 3 (#46f5a3)
L 4 (#935370)
U 4 (#46f5a1)
L 5 (#3ca140)
U 6 (#07b1e3)
L 5 (#61ecd0)
U 5 (#654743)
L 5 (#3cec42)
U 6 (#30bb83)
R 3 (#920782)
U 6 (#1f9323)
R 8 (#3d8aa2)
U 8 (#7492c3)
R 3 (#301cd2)
U 3 (#32e2f1)
R 4 (#6936f2)
U 6 (#32e2f3)
R 6 (#5112c2)
U 7 (#535b53)
L 10 (#61f4d0)
U 3 (#915863)
L 2 (#51d540)
U 5 (#32dee1)
L 10 (#4ec320)
U 5 (#406bc1)
L 2 (#1b3890)
U 3 (#681181)
L 6 (#35ed60)
D 9 (#153fd3)
L 5 (#323e30)
U 5 (#381ad3)
L 3 (#69a550)
U 3 (#310f63)
L 4 (#2cbb80)
U 5 (#3448a3)
R 6 (#206282)
U 5 (#202ab1)
L 6 (#83af82)
U 4 (#202ab3)
L 4 (#248d02)
D 9 (#28a983)
L 4 (#32cf10)
D 7 (#249d73)
R 4 (#2f5c70)
D 6 (#021c93)
L 7 (#957782)
D 6 (#550e53)
R 5 (#957780)
D 6 (#50bb13)
R 9 (#49b7f2)
U 6 (#096e93)
R 4 (#769452)
D 3 (#6dc543)
R 5 (#2ad352)
D 7 (#167963)
L 10 (#673682)
D 5 (#152883)
L 10 (#13f332)
D 3 (#996721)
L 4 (#4be2a2)
D 4 (#9c2443)
L 4 (#2b83b0)
D 3 (#5d63b3)
L 9 (#9cfd40)
D 7 (#49e793)
L 7 (#0b5422)
D 8 (#5c51b3)
L 2 (#6db152)
D 4 (#215b53)
L 3 (#38dc12)
D 8 (#7dad01)
L 6 (#559e22)
D 3 (#929d23)
L 2 (#0f7560)
D 6 (#448d13)
L 7 (#73a972)
D 2 (#2221c3)
L 3 (#73a970)
D 5 (#53b553)
R 10 (#513590)
D 3 (#293c83)
L 10 (#58e2e0)
D 4 (#54dd21)
L 5 (#1bcdf2)
D 5 (#4b0b71)
L 5 (#1bcdf0)
U 6 (#43b811)
L 5 (#4df1d0)
U 6 (#36d6a3)
R 5 (#3bfb20)
U 5 (#75de61)
L 5 (#1e0ec2)
U 4 (#30b571)
L 7 (#2dfd20)
D 5 (#49ad61)
L 2 (#2dfd22)
D 11 (#715d41)
L 3 (#1e0ec0)
U 4 (#0f2091)
L 4 (#9d29c0)
U 9 (#475a73)
L 2 (#108610)
U 3 (#1e5423)
L 8 (#394192)
U 3 (#0274b3)

89
aoc2023/day18/main.go Normal file
View File

@@ -0,0 +1,89 @@
package main
import (
"bufio"
_ "embed"
"fmt"
"strconv"
"strings"
aoc "go.sour.is/advent-of-code"
"golang.org/x/exp/maps"
)
// var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(run)) }
type result struct {
valuePT1 int
valuePT2 int
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(scan *bufio.Scanner) (*result, error) {
var vecsPT1 []aoc.Vector
var vecsPT2 []aoc.Vector
for scan.Scan() {
text := scan.Text()
if len(text) == 0 {
continue
}
v, color := fromLine(text)
vecsPT1 = append(vecsPT1, v)
vecsPT2 = append(vecsPT2, fromColor(color))
}
return &result{
valuePT1: findArea(vecsPT1),
valuePT2: findArea(vecsPT2),
}, nil
}
var OFFSET = map[string]aoc.Point[int]{
"R": {0, 1},
"D": {1, 0},
"L": {0, -1},
"U": {-1, 0},
}
var OFFSET_INDEXES = maps.Values(OFFSET)
func fromLine(text string) (aoc.Vector, string) {
v := aoc.Vector{}
s, text, _ := strings.Cut(text, " ")
v.Offset = OFFSET[s]
s, text, _ = strings.Cut(text, " ")
v.Scale = aoc.Atoi(s)
_, text, _ = strings.Cut(text, "(#")
s, _, _ = strings.Cut(text, ")")
return v, s
}
func fromColor(c string) aoc.Vector {
scale, _ := strconv.ParseInt(c[:5], 16, 64)
offset := OFFSET_INDEXES[c[5]-'0']
return aoc.Vector{
Offset: offset,
Scale: int(scale),
}
}
func findArea(vecs []aoc.Vector) int {
shoelace := []aoc.Point[int]{{0, 0}}
borderLength := 0
for _, vec := range vecs {
shoelace = append(shoelace, shoelace[len(shoelace)-1].Add(vec.Point()))
borderLength += vec.Scale
}
return aoc.NumPoints(shoelace, borderLength)
}

View File

@@ -0,0 +1,42 @@
package main
import (
"bufio"
"bytes"
"testing"
_ "embed"
"github.com/matryer/is"
)
//go:embed example.txt
var example []byte
//go:embed input.txt
var input []byte
func TestExample(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(example))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 62)
is.Equal(result.valuePT2, 952408144115)
}
func TestSolution(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(input))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.True(result.valuePT1 < 68834) // first attempt too high.
is.Equal(result.valuePT1, 46334)
is.Equal(result.valuePT2, 102000662718092)
}

255
aoc2023/day19/main.go Normal file
View File

@@ -0,0 +1,255 @@
package main
import (
"bufio"
_ "embed"
"fmt"
"strings"
aoc "go.sour.is/advent-of-code"
)
// var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(run)) }
type result struct {
valuePT1 int
valuePT2 uint
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(scan *bufio.Scanner) (*result, error) {
var workflows = make(map[string][]rule)
var parts []part
for scan.Scan() {
text := strings.TrimSuffix(scan.Text(), "}")
if len(text) == 0 {
continue
}
// Is Part
if p, ok := scanPart(text); ok {
parts = append(parts, p)
continue
}
if name, r, ok := scanRule(text); ok {
workflows[name] = r
}
}
var result result
result.valuePT1 = solveWorkflow(parts, workflows)
result.valuePT2 = solveRanges(workflows)
return &result, nil
}
type part struct {
x, m, a, s int
}
func (p part) String() string {
return fmt.Sprintf("{x:%v m:%v a:%v s:%v}", p.x, p.m, p.a, p.s)
}
func scanPart(text string) (part, bool) {
var p part
// Is Part
if text[0] == '{' {
for _, s := range strings.Split(text[1:], ",") {
a, b, _ := strings.Cut(s, "=")
i := aoc.Atoi(b)
switch a {
case "x":
p.x = i
case "m":
p.m = i
case "a":
p.a = i
case "s":
p.s = i
}
}
return p, true
}
return p, false
}
type rule struct {
match string
op string
value int
queue string
}
func scanRule(text string) (string, []rule, bool) {
name, text, _ := strings.Cut(text, "{")
var r []rule
for _, s := range strings.Split(text, ",") {
if a, b, ok := strings.Cut(s, "<"); ok {
b, c, _ := strings.Cut(b, ":")
r = append(r, rule{
match: a,
op: "<",
value: aoc.Atoi(b),
queue: c,
})
continue
}
if a, b, ok := strings.Cut(s, ">"); ok {
b, c, _ := strings.Cut(b, ":")
r = append(r, rule{
match: a,
op: ">",
value: aoc.Atoi(b),
queue: c,
})
continue
}
// default queue comes last
r = append(r, rule{queue: s})
break
}
return name, r, len(r) > 0
}
func (r rule) Match(p part) bool {
var value int
switch r.match {
case "x":
value = p.x
case "m":
value = p.m
case "a":
value = p.a
case "s":
value = p.s
default:
return true // default to new queue
}
if r.op == ">" && value > r.value {
return true
} else if r.op == "<" && value < r.value {
return true
}
return false // no match
}
func solveWorkflow(parts []part, workflows map[string][]rule) int {
// var rejected []part
var accepted []part
for _, p := range parts {
workflow := "in"
nextStep:
for workflow != "" {
for _, r := range workflows[workflow] {
if !r.Match(p) {
continue
}
workflow = r.queue
if workflow == "A" {
accepted = append(accepted, p)
workflow = ""
break nextStep
}
if workflow == "R" {
// rejected = append(rejected, p)
workflow = ""
break nextStep
}
continue nextStep
}
}
}
sum := 0
for _, p := range accepted {
sum += p.x
sum += p.m
sum += p.a
sum += p.s
}
return sum
}
func solveRanges(workflows map[string][]rule) uint {
pq := aoc.PriorityQueue(func(a, b *queue) bool { return false })
pq.Insert(&queue{
"in",
block{
ranger{1, 4000},
ranger{1, 4000},
ranger{1, 4000},
ranger{1, 4000},
}})
var accepted []block
// var rejected []block
for !pq.IsEmpty() {
current := pq.ExtractMin()
for _, rule := range workflows[current.name] {
next := &queue{name: rule.queue, block: current.block}
switch rule.match {
case "x":
current.x, next.x = split(current.x, rule.value, rule.op == ">")
case "m":
current.m, next.m = split(current.m, rule.value, rule.op == ">")
case "a":
current.a, next.a = split(current.a, rule.value, rule.op == ">")
case "s":
current.s, next.s = split(current.s, rule.value, rule.op == ">")
}
switch next.name {
case "R":
// rejected = append(rejected, next.block)
case "A":
accepted = append(accepted, next.block)
default:
pq.Insert(next)
}
}
}
var sum uint
for _, a := range accepted {
sum += uint((a.x[1] - a.x[0] + 1) * (a.m[1] - a.m[0] + 1) * (a.a[1] - a.a[0] + 1) * (a.s[1] - a.s[0] + 1))
}
return sum
}
type ranger [2]int
type block struct {
x, m, a, s ranger
}
type queue struct {
name string
block
}
func split(a ranger, n int, gt bool) (current ranger, next ranger) {
if gt { // x > N => [0,N] [N++,inf]
return ranger{a[0], n}, ranger{n + 1, a[1]}
}
// x < N => [N,inf] [0,N--]
return ranger{n, a[1]}, ranger{a[0], n - 1}
}

View File

@@ -25,7 +25,7 @@ func TestExample(t *testing.T) {
t.Log(result) t.Log(result)
is.Equal(result.valuePT1, 19114) is.Equal(result.valuePT1, 19114)
is.Equal(result.valuePT2, 0) is.Equal(result.valuePT2, uint(167409079868000))
} }
func TestSolution(t *testing.T) { func TestSolution(t *testing.T) {
@@ -37,5 +37,5 @@ func TestSolution(t *testing.T) {
t.Log(result) t.Log(result)
is.Equal(result.valuePT1, 377025) is.Equal(result.valuePT1, 377025)
is.Equal(result.valuePT2, 0) is.Equal(result.valuePT2, uint(135506683246673))
} }

View File

@@ -0,0 +1,5 @@
broadcaster -> a, b, c
%a -> b
%b -> c
%c -> inv
&inv -> a

View File

@@ -0,0 +1,5 @@
broadcaster -> a
%a -> inv, con
&inv -> b
%b -> con
&con -> output

58
aoc2023/day20/input.txt Normal file
View File

@@ -0,0 +1,58 @@
%vg -> lf, vd
%dr -> kg
%cn -> mv, pt
%rq -> bk, gr
%vp -> lp, bk
%kg -> lv
%lv -> jc, tp
%sj -> rm, vd
%jc -> tp, qr
%km -> tp, dr
%jx -> cn
&vd -> tf, lf, nb, cx, hx, lr
%lp -> jt, bk
%vj -> ps
broadcaster -> km, lr, xh, rf
%dj -> pt, gc
%cg -> vd, hx
&ln -> tg
%fl -> pt, sk
%lm -> tr, bk
%lr -> vd, vg
&pt -> vq, rf, cm, jx, rg
%cx -> gp
%gp -> vd, sj
&db -> tg
%st -> vd
%jt -> bk
%jh -> lm, bk
%xf -> bd, tp
%gc -> cm, pt
&tp -> dr, km, kg, db, vj, qr
%ps -> xf, tp
%rf -> pt, dj
%lf -> nb
%bd -> tp, gg
%dk -> tp, vj
%mn -> jh, bk
&tg -> rx
%ql -> bk, zx
%tr -> bk, vp
%sk -> pt
%nb -> cg
%sb -> vd, cx
%qr -> dk
%xh -> bk, ql
%rg -> sd
%hx -> sb
%sd -> pt, jx
%gr -> bk, mn
%gg -> tp
%zx -> rq
&bk -> xh, ln, zx
%rm -> st, vd
%hq -> fl, pt
&vq -> tg
%cm -> rg
&tf -> tg
%mv -> pt, hq

282
aoc2023/day20/main.go Normal file
View 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
}

View File

@@ -0,0 +1,56 @@
package main
import (
"bufio"
"bytes"
"testing"
_ "embed"
"github.com/matryer/is"
)
//go:embed example1.txt
var example1 []byte
//go:embed example2.txt
var example2 []byte
//go:embed input.txt
var input []byte
func TestExample1(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(example1))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 32000000)
is.Equal(result.valuePT2, 0)
}
func TestExample2(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(example2))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 11687500)
is.Equal(result.valuePT2, 0)
}
func TestSolution(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(input))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 819397964)
is.Equal(result.valuePT2, 252667369442479)
}

11
aoc2023/day21/example.txt Normal file
View File

@@ -0,0 +1,11 @@
...........
.....###.#.
.###.##..#.
..#.#...#..
....#.#....
.##..S####.
.##..#...#.
.......##..
.##.#.####.
.##..##.##.
...........

131
aoc2023/day21/input.txt Normal file
View File

@@ -0,0 +1,131 @@
...................................................................................................................................
.#.......#..#...#.......#......#....#..#...#...#....#.#..........................................#...............#..........#......
.............##..................#......#.#....#.......................##..#........................#......#..........#............
......#..........................#....#.....#.............#................##....#.#.............#.........#.##...........#........
.#................#............................#...........................#..##.....#..................#..##..#.#.........##......
.....#.............#.....##.............##..........#...........#.............#.....#...........#.#.......#....#......#..........#.
........#....................#....#.#.#......##........#...........#...........#..........#...#..........#......................#..
.........#.#...#.......#........#........##...#...#..##........................................##...#.#........................#...
......#.....#..#..#.#..#..............#...#..#.....#...........#.....#........#.#...........#...........#.#...............#.....#..
...........#.......####..#.#..............##................#.#.#.....................##.....................#...#..............#..
......###...#......#................##...#...#....#...........#...#..............#.........#..#..................................#.
...............#..##..........#...........................##......#.##.........................#..#.#...........#.#...........#....
...##........#...#...#...##...##...........#..#...................#...................#.#..#.........#.......#..#...........##...#.
................#.....#..##......#.....#.....##............#..#..........##...........................#.#.......##.....#.....#.....
.#..#.......#.#...#..##.....#............................#......#...#....#................#.#..#.....#.......##................#...
...............#.....#........................#..........#.....#..............................................#..................#.
.....#......#..........................................#....................................#..#.......#.#..#......#.#....#..##....
............##............#.......###.......................#..#....#......................................#..#.........#..........
..#...............#.....#...#...#......................#...#.#..............................#.#..#.#.....#.#.#..#....#.....#...##..
.#.............................##.................#.......#.......##....#....................#.....#.#........#.....#........#.....
.#....##...................##.....#.#..............#.#....#....#..#....#......#..........#.....##............#....#.............##.
.........#....#.....#..#.........#....#.#..........#...#...#.......#....#..##.......................#.#..#........#..#....#..#.#...
..#..................#.......#..#.#..............##.......#........#..............#.........#..#....#......#..#..........#.........
........#.....#......#.....#......#...#.......#....#.......#.#..#................#....................##.............#.......#.....
..#.................#..............#...........................................#.....#..................#...#.#..................#.
.......#......#.....#...........................#.....#..................#.....................#.....#.#......#........#.#.......#.
..#.#.#...................#...#..#................#....#.......#......................#...............#.........##...#.#.....###...
.....#...#....##....#........####...........#.................#...#...........................................#..............##....
..##.#..#.#..........#.#.#..#................................#..#.............#..#......#...........................#.##...........
..............#.............................##........#..##........................#.............................#........#........
........#.........#........#..#........#..#........#...#.#........#...........#.........................#.#..........#...#......#..
.........##.....#........#.....................#..#.............#.....#........#....................#....#.#.#......#.....#........
......................#...................####..#.........#....#.........#...........#..................#..#.................#.....
..#.........#...#.....##................##.##....#.....#....#..............................#..#.............#..#...................
..........##......#..#..............#.#....#......#................#.....#....#..............#..................#..................
.#.#..####...#....................#.#.#.....#...#...................#....#.#.....#.#.......#.#...........#......#.#................
.......#.........#..#.#..............###.......#....#.........................#.......#.###...#............#....#.#..#....###.#....
........#....#...#......#.................#..........................#.........................#...........##.............#.#......
.#..............#.....................#......#.............##............#..#..........#...................#...#....#..............
......#..#..#.#...............#........###.......#.#...........#...........#.#.........#..#.....................#......#..#.#......
.....#...............#.........#....#..........#.......#.......#......#...#..##.....#.....#........#.#.......#.......#..#...#......
..#............#.....................#...#.......#....###...........#.....#.#.................#................#.........#..##.#...
..............................#.....#..................................#.....##...............#.......#.........#.....#....##......
..#...##...#...#..............#.................##..#......#.................#....#......#...#...#......#..........................
.........#....#..............#........#..#...............#....#...#.....#..#......#.........#.......#.#..#........#...........#....
........#..#....................#.........#...##.#.#..............#......#.#..........##...##....#......................#..........
.##..#....#....#.......##......#............#..#......#.....##..................#####..#...#......#.#...#..........#.#.....#..#....
..#...........#....................#.......#......#.........#...............#......#........##........#.................#.....#.#..
..#....#.#...............#.#.........................#.............####..............................##................###.........
.....#.......................................#....#...##...#.......#.......#.....#.##..##.................#.....................##.
.........#...........#..#..##.#..........#..#.........#..#.....#...................................##....#...............#..#.#....
.....#..#...........##............#........#..................#............#..........#..........#..#...........#..................
............................#.........#...............#..................#.#....#.#..#........#.....#...........#...........#......
................#...##.#....#..##..........#.#........##.#..#..#.....................#....#.................#.#...............#....
.#.....#..............#.#..........#..#........#...............#..#.#..##..#.#.#.........................#.................#.......
....#..............#................#.....#..#.......#..#.#.........#..........#..........#.....#..........##.....#............#...
..............##...........#.......#......#..................#.......#.....#.#...#...............#.#........#......#............#..
................#.....#....#........#....#.......#.#.##.....#...#..#.##...#................#.#.....#....#.............#............
...........#.#.##..####.....#....#.#...#.#...........#...#.......................#.#....#.....#..#................###..............
...................#....#..........#.#..##.....#..#..#......###............#..#...........#....#......#............................
...........................................#.......#..............#.##.......##.......#...#.....#.#..#.....#..###..................
............###........#.......#.#....#.....#....#..#........#.........##....#.....#..........#......#............#..#.#...........
............#..........#................##.#..............#.....#................#....................................#..#.........
...........#.....#.....................#...#.....#.......#..........#....#.....###.....##.#.##.#.....#......#......#.......#.......
.....................#..#.....#...##.....#..#...........#....#....##............##.................##............##................
.................................................................S.................................................................
........#.#........#..........#.....#......#........#.#............#.#.........##...#............#...#.....#...........#.....#.....
..................##.......#......#..#..................#..##......#.........#...#.........#............#....#...........##........
..................#...........#.##.......#..............#....................#.#....#...##...#.....#.......#..#.....##.............
...........#....#....##...#................................#.........#.................#....#.......................#...#..........
.............#.#.#.....#.#...#.......#.#...........#....#.#.........#........##......#.......#.......##...#..........#.##..........
...........##.#....#....#..#.....#...............#......................#...........#.....#...........#.#.......#..................
.#.......................#.#...##.#....#.#...........#.#....##.##......#........................##....#.#....#.....................
...#..................#.#...........##....###.................#....................##......#.....#............#.##....#.......##...
.#..................####...#.#..#.##.#...####...#......#....................#..........................#....#......................
.....#..........#.....#.#...............#.........##...#......#.#.....#...........#.....#............##......#.....#...............
......#........#....#..#............................###.#...##........#........#.................#..#........#...............##....
......................#.........................##....#...#..............#..#............#.#....#......##.#......#.........##......
..................#....#...#.#.......#..............#..#..#...#.......#...#.....#.....#...............#.#.#...............#........
...#...##......................##..##...........#......#.............#............#...........##.......#....#......................
.............................##...........##...#...#.....#....#.......#.#..#.....##...............#..#.#......#..............##....
...#..#.#...#.......#..................#............#....#.#.##.#.........#......#........#..#..........#....##...........#....#...
.....#.............................#......#.#.....#.##.#.................#.........#..#..#.#.#........................#.#.......#..
....#........#........#....#.#.#.....#.##............###.#..........#...##......#........##...#.........#.............#........#...
..#..............................#.............................#......#...................#...#......#.............#...............
.......#...#...............#.................##....................#....##.......#....##....##...#..................#..............
.........................#...#..#.....##.............#...##.......#.....#...#..............#.....#.#.#..#........................#.
......#.......##.#.............#....................#...#...........#...#..##....#.....#............#...........#........#.........
...#....#...#......#........................#.....#.........#......#........#.....#.#...........#.#..............#......#....#.....
........#..........#...................#...........##.#..#...#................#....##.............#................#....#..........
........#.......#....#.............#..........#...................#.#....#.#........#..#..............................#..........#.
............#........#....................#.#.........#......#.............#................#...#.............#....#...............
..#..............................#..#....##.....#......................##...#..#.........#......#......................#...#...#.#.
.##....#.............#...........##..................#...#..............#.......#................................#.........#.......
.....#......#.#.....##...........#.....#.......#..........##..#.............#.#.........#.#.#.............##........#......#..#....
.......#.......#.#.#..#......................#....#............##....#...........#.........................#......#................
.........##.........#..............#.#.#....#...#.......#.................................#..##..................##.###.##...#.....
......................#...#.#.......#..#.#..........#........#.......#.................#..................................#........
....##........#.........#.........................#................#......#...#.....#..................................#..#.#......
...##..............#..................#...#......#........###..#.......#..........#..............................#......#..........
.#.#.#....#..........#......#.#.........#.....#...............................#.....#.#............#....#........#.............#...
........#.........#.........#......................#..#......##.....#..#..........................#......##....#......##.##.....#..
.##...#.......#.#....#..#.#...................#.........#....#...........#.....#.........#............##......#............#.......
.##..#.........#..........#.#.................................#.#.#...............................#............#......##...#.#.....
......#........#..#...#............#..............#............#......##.....#.................................#......#.#.....#....
..........#........#...........#....................................#.....#...............................#............##....#.##..
........#.............#..#......##..................#.............#..#...#.#.....#...#...............#........................#....
....#...............#..........#....#...........................#....##.##...................#.#.......#...#.##....#........##..#..
......#.....#..#..........###...#.................####.###..........#...........#..........#......#............................#...
.#...#......#........#..#............##...............#.##......#...#.....#....................#.........#............#...#........
................##...................#.##..............#...#..#.......#.......###........#..#..#........#...##.....................
..............#....#..#..#.............##..............#................................#.....#..#....###.##..............#........
..#..............#........................................#..........#.....#..................#............#..#....................
.........#...#.....#...#...##...........#.###............##...#........#......................##......#....#.......#...............
....#....#.....#.......#......................................#.#.#....#..#..#..........#...................#........#...#.........
..#..#..................#..............#...#..#.........#......#....#.#................##..........#..#................#...........
...#...................#...........#....#...#.............##...#.......#.#..........#..#...............#....#....#.............#...
.......................##.#.#..##........#....#.........#.#.#.....##..............#.......#.......##.#..........#.#................
.....#..#..................#..##....#.......#.............#...#.....#.............#.............#.#...............#.....##......##.
...#.#.....#..........#.#............#..#..........................##.............#....#.......#.#...#...#....................#.#..
............##.#............#....#....#....#..##...#...............................#...#...#.........#.......................##.##.
....#.#...............#...#.......#............#..#...........................#..............#..........#....#...#...#..#...#....#.
.......#..#..#.#..#......#..........................#...............#.........#...........#................#..#...#................
...#..#...#.....#.#.......#....................................................#........#..........#.#...#......#..........#.......
..#...#.......#..#..............#.#...#.....#...#....#............#..........##...#.........##.............#.......................
...#.............#...#....#...#.....#.#.#..............#..........#........#........##...........#..#.#......................#.....
.#.......#.................#...............#..........#.....................#.....#............#......##....#.....#...#....###.....
...##...........#..........#.#........#............#..#.#........................#.....##............#...##.#.......#.##....#......
...........#........#...........#.......#......#...#.....#............................#........#..#................#...#....##.....
...##.##.........#.####..#............#..#.....#.......................#......#..........#.#..#.#....##........#....#.....#..#..##.
...................................................................................................................................

99
aoc2023/day21/main.go Normal file
View File

@@ -0,0 +1,99 @@
package main
import (
"bufio"
_ "embed"
"fmt"
aoc "go.sour.is/advent-of-code"
)
// var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(runner(64))) }
type result struct {
valuePT1 int
valuePT2 int
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func runner(rounds int) func(scan *bufio.Scanner) (*result, error) {
return func(scan *bufio.Scanner) (*result, error) {
var garden garden
for scan.Scan() {
txt := scan.Text()
garden.m = append(garden.m, []rune(txt))
for i, c := range txt {
if c == 'S' {
garden.start[0] = len(garden.m) - 1
garden.start[1] = i
}
}
}
garden.Step(rounds)
return &result{
valuePT1: len(garden.steps[len(garden.steps)-1]),
}, nil
}
}
type garden struct {
start aoc.Point[int]
m [][]rune
steps []aoc.Set[aoc.Point[int]]
}
func (g *garden) Neighbors(p aoc.Point[int]) []aoc.Point[int] {
var neighbors []aoc.Point[int]
for _, n := range []aoc.Point[int]{
{p[0] - 1, p[1]},
{p[0] + 1, p[1]},
{p[0], p[1] - 1},
{p[0], p[1] + 1},
} {
if n[0] >= 0 && n[0] < len(g.m) && n[1] >= 0 && n[1] < len(g.m[0]) && g.m[n[0]][n[1]] != '#' {
neighbors = append(neighbors, n)
}
}
return neighbors
}
func (g *garden) Step(n int) {
if len(g.steps) == 0 {
g.steps = append(g.steps, aoc.NewSet(g.start))
}
for step := range(n) {
g.steps = append(g.steps, aoc.NewSet[aoc.Point[int]]())
for p := range g.steps[step] {
for _, n := range g.Neighbors(p) {
g.steps[step+1].Add(n)
}
}
}
}
func (g garden) String() string {
var b []rune
for i, line := range g.m {
if i == g.start[0] {
line[g.start[1]] = 'X'
}
if steps := len(g.steps) - 1; steps > 0 {
for p := range g.steps[len(g.steps)-1] {
if p[0] == i {
line[p[1]] = 'O'
}
}
}
b = append(b, line...)
b = append(b, '\n')
}
return string(b)
}

View File

@@ -0,0 +1,41 @@
package main
import (
"bufio"
"bytes"
"testing"
_ "embed"
"github.com/matryer/is"
)
//go:embed example.txt
var example []byte
//go:embed input.txt
var input []byte
func TestExample(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(example))
result, err := runner(6)(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 16)
is.Equal(result.valuePT2, 0)
}
func TestSolution(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(input))
result, err := runner(64)(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 3709)
is.Equal(result.valuePT2, 0)
}

13
aoc2023/day25/example.txt Normal file
View File

@@ -0,0 +1,13 @@
jqt: rhn xhk nvd
rsh: frs pzl lsr
xhk: hfx
cmg: qnr nvd lhk bvb
rhn: xhk bvb hfx
bvb: xhk hfx
pzl: lsr hfx nvd
qnr: nvd
ntq: jqt hfx bvb xhk
nvd: lhk
lsr: lhk
rzs: qnr cmg lsr rsh
frs: qnr lhk lsr

1261
aoc2023/day25/input.txt Normal file

File diff suppressed because it is too large Load Diff

63
aoc2023/day25/main.go Normal file
View File

@@ -0,0 +1,63 @@
package main
import (
"bufio"
_ "embed"
"fmt"
"iter"
"strings"
aoc "go.sour.is/advent-of-code"
)
// var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(run)) }
type result struct {
valuePT1 int
valuePT2 int
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(scan *bufio.Scanner) (*result, error) {
g := aoc.Graph[string, int]()
var root string
for scan.Scan() {
line := scan.Text()
v, lis, ok := strings.Cut(line, ": ")
if !ok {
continue
}
if root == "" {
root = v
}
for _, l := range strings.Split(lis, " ") {
g.AddEdge(v, l, 1)
g.AddEdge(l, v, 1)
}
}
for i, v := range enumerate(g.BFS(root)) {
fmt.Println(i, v)
}
return &result{}, nil
}
func enumerate[T any](vs iter.Seq[T]) iter.Seq2[int, T] {
i := 0
return func(yield func(int, T) bool) {
for v := range vs {
if !yield(i, v) {
return
}
i++
}
}
}

View File

@@ -24,7 +24,7 @@ func TestExample(t *testing.T) {
is.NoErr(err) is.NoErr(err)
t.Log(result) t.Log(result)
is.Equal(result.valuePT1, 102) is.Equal(result.valuePT1, 50)
is.Equal(result.valuePT2, 0) is.Equal(result.valuePT2, 0)
} }

View File

@@ -0,0 +1,6 @@
3 4
4 3
2 5
1 3
3 9
3 3

1000
aoc2024/day01/input.txt Normal file

File diff suppressed because it is too large Load Diff

86
aoc2024/day01/main.go Normal file
View File

@@ -0,0 +1,86 @@
package main
import (
"bufio"
_ "embed"
"fmt"
"iter"
"slices"
"sort"
aoc "go.sour.is/advent-of-code"
)
// var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(run)) }
type result struct {
valuePT1 int
valuePT2 int
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(scan *bufio.Scanner) (*result, error) {
var (
left []int
right []int
)
for scan.Scan() {
txt := scan.Text()
var l, r int
_, err := fmt.Sscanf(txt, "%d %d", &l, &r)
if err != nil {
return nil, err
}
left = append(left, l)
right = append(right, r)
}
sort.Ints(left)
sort.Ints(right)
result := &result{}
result.valuePT1 = aoc.Reduce(func(i int, z pair[int, int], sum int) int {
return sum + aoc.ABS(z.L-z.R)
}, 0, zip(slices.Values(left), slices.Values(right)))
rmap := aoc.Reduce(func(i int, z int, m map[int]int) map[int]int {
m[z]++
return m
}, make(map[int]int), slices.Values(right))
for _, v := range left {
if r, ok := rmap[v]; ok {
result.valuePT2 += v*r
}
}
return result, nil
}
type pair[L, R any] struct {
L L
R R
}
func zip[L, R any](l iter.Seq[L], r iter.Seq[R]) iter.Seq[pair[L,R]] {
return func(yield func(pair[L, R]) bool) {
pullR, stop := iter.Pull(r)
defer stop()
for l := range l {
r, _ := pullR()
if !yield(pair[L, R]{L: l, R: r}) {
return
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More