Compare commits
2 commits
825f608c04
...
b4f03940e9
| Author | SHA1 | Date | |
|---|---|---|---|
| b4f03940e9 | |||
| 9bcd3a2f6f |
5 changed files with 1231 additions and 0 deletions
20
day8/input0.txt
Normal file
20
day8/input0.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
162,817,812
|
||||||
|
57,618,57
|
||||||
|
906,360,560
|
||||||
|
592,479,940
|
||||||
|
352,342,300
|
||||||
|
466,668,158
|
||||||
|
542,29,236
|
||||||
|
431,825,988
|
||||||
|
739,650,466
|
||||||
|
52,470,668
|
||||||
|
216,146,977
|
||||||
|
819,987,18
|
||||||
|
117,168,530
|
||||||
|
805,96,715
|
||||||
|
346,949,466
|
||||||
|
970,615,88
|
||||||
|
941,993,340
|
||||||
|
862,61,35
|
||||||
|
984,92,344
|
||||||
|
425,690,689
|
||||||
1000
day8/input1.txt
Normal file
1000
day8/input1.txt
Normal file
File diff suppressed because it is too large
Load diff
208
day8/main.go
Normal file
208
day8/main.go
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"slices"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/dominikbraun/graph"
|
||||||
|
)
|
||||||
|
|
||||||
|
func readLines(filename string) []string {
|
||||||
|
raw, err := os.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return strings.Split(string(raw), "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// input1 80446
|
||||||
|
func main() {
|
||||||
|
filename := "input0.txt"
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
filename = os.Args[1]
|
||||||
|
}
|
||||||
|
lines := readLines(filename)
|
||||||
|
p := parsePlayground(lines)
|
||||||
|
circuits, err := p.wireClosest(1000)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
counts := map[uint]uint{}
|
||||||
|
for _, circuit := range circuits {
|
||||||
|
counts[circuit]++
|
||||||
|
}
|
||||||
|
totals := []uint{}
|
||||||
|
for _, v := range counts {
|
||||||
|
totals = append(totals, v)
|
||||||
|
}
|
||||||
|
slices.Sort(totals)
|
||||||
|
slices.Reverse(totals)
|
||||||
|
fmt.Printf("%v\n", totals[0]*totals[1]*totals[2])
|
||||||
|
xx, err := p.wireAll()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("%d\n", xx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parsePlayground(lines []string) playground {
|
||||||
|
p := playground{
|
||||||
|
boxes: []box{},
|
||||||
|
distances: graph.New(boxHash, graph.Weighted()),
|
||||||
|
}
|
||||||
|
for _, line := range lines {
|
||||||
|
parts := strings.Split(line, ",")
|
||||||
|
b := box{line: line}
|
||||||
|
b.x, _ = strconv.Atoi(parts[0])
|
||||||
|
b.y, _ = strconv.Atoi(parts[1])
|
||||||
|
b.z, _ = strconv.Atoi(parts[2])
|
||||||
|
_ = p.distances.AddVertex(b)
|
||||||
|
for _, c := range p.boxes {
|
||||||
|
_ = p.distances.AddEdge(b.line, c.line, graph.EdgeWeight(b.distanceTo(c)))
|
||||||
|
}
|
||||||
|
p.boxes = append(p.boxes, b)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *playground) wireClosest(n uint64) (map[string]uint, error) {
|
||||||
|
edges, err := p.distances.Edges()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
slices.SortFunc(edges, func(e1, e2 graph.Edge[string]) int {
|
||||||
|
return e1.Properties.Weight - e2.Properties.Weight
|
||||||
|
})
|
||||||
|
nextCircuit := uint(1)
|
||||||
|
circuits := map[string]uint{}
|
||||||
|
for i := range n {
|
||||||
|
edge := edges[i]
|
||||||
|
sourceCircuit := circuits[edge.Source]
|
||||||
|
targetCircuit := circuits[edge.Target]
|
||||||
|
if sourceCircuit == 0 && targetCircuit == 0 {
|
||||||
|
circuits[edge.Source] = nextCircuit
|
||||||
|
circuits[edge.Target] = nextCircuit
|
||||||
|
nextCircuit++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if sourceCircuit == 0 {
|
||||||
|
circuits[edge.Source] = targetCircuit
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if targetCircuit == 0 {
|
||||||
|
circuits[edge.Target] = sourceCircuit
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if sourceCircuit == targetCircuit {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for k, v := range circuits {
|
||||||
|
if v == targetCircuit {
|
||||||
|
circuits[k] = sourceCircuit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return circuits, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *playground) wireAll() (int, error) {
|
||||||
|
edges, err := p.distances.Edges()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
slices.SortFunc(edges, func(e1, e2 graph.Edge[string]) int {
|
||||||
|
return e1.Properties.Weight - e2.Properties.Weight
|
||||||
|
})
|
||||||
|
circuitsInUse := 0
|
||||||
|
nextCircuit := uint(1)
|
||||||
|
circuits := map[string]uint{}
|
||||||
|
for _, edge := range edges {
|
||||||
|
sourceCircuit := circuits[edge.Source]
|
||||||
|
targetCircuit := circuits[edge.Target]
|
||||||
|
if sourceCircuit == 0 && targetCircuit == 0 {
|
||||||
|
circuits[edge.Source] = nextCircuit
|
||||||
|
circuits[edge.Target] = nextCircuit
|
||||||
|
nextCircuit++
|
||||||
|
circuitsInUse++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if sourceCircuit == 0 {
|
||||||
|
circuits[edge.Source] = targetCircuit
|
||||||
|
if circuitsInUse == 1 {
|
||||||
|
count, _ := p.distances.Order()
|
||||||
|
if count == len(circuits) {
|
||||||
|
v1, _ := p.distances.Vertex(edge.Source)
|
||||||
|
v2, _ := p.distances.Vertex(edge.Target)
|
||||||
|
return v1.x * v2.x, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if targetCircuit == 0 {
|
||||||
|
circuits[edge.Target] = sourceCircuit
|
||||||
|
if circuitsInUse == 1 {
|
||||||
|
count, _ := p.distances.Order()
|
||||||
|
if count == len(circuits) {
|
||||||
|
v1, _ := p.distances.Vertex(edge.Source)
|
||||||
|
v2, _ := p.distances.Vertex(edge.Target)
|
||||||
|
return v1.x * v2.x, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if sourceCircuit == targetCircuit {
|
||||||
|
if circuitsInUse == 1 {
|
||||||
|
count, _ := p.distances.Order()
|
||||||
|
if count == len(circuits) {
|
||||||
|
v1, _ := p.distances.Vertex(edge.Source)
|
||||||
|
v2, _ := p.distances.Vertex(edge.Target)
|
||||||
|
return v1.x * v2.x, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for k, v := range circuits {
|
||||||
|
if v == targetCircuit {
|
||||||
|
circuits[k] = sourceCircuit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
circuitsInUse--
|
||||||
|
if circuitsInUse == 1 {
|
||||||
|
count, _ := p.distances.Order()
|
||||||
|
if count == len(circuits) {
|
||||||
|
v1, _ := p.distances.Vertex(edge.Source)
|
||||||
|
v2, _ := p.distances.Vertex(edge.Target)
|
||||||
|
return v1.x * v2.x, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v, _ := p.distances.Order()
|
||||||
|
return 0, fmt.Errorf("exhausted edges without reaching full connectivity %v", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
type playground struct {
|
||||||
|
boxes []box
|
||||||
|
distances graph.Graph[string, box]
|
||||||
|
}
|
||||||
|
|
||||||
|
func boxHash(b box) string {
|
||||||
|
return b.line
|
||||||
|
}
|
||||||
|
|
||||||
|
type box struct {
|
||||||
|
line string
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
z int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b box) distanceTo(c box) int {
|
||||||
|
x := c.x - b.x
|
||||||
|
y := c.y - b.y
|
||||||
|
z := c.z - b.z
|
||||||
|
// no need to sqrt since we only care about relative distances
|
||||||
|
return x*x + y*y + z*z
|
||||||
|
}
|
||||||
1
go.mod
1
go.mod
|
|
@ -3,6 +3,7 @@ module ballstads.name/aoc2025
|
||||||
go 1.25.5
|
go 1.25.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/dominikbraun/graph v0.23.0 // indirect
|
||||||
github.com/kelindar/bitmap v1.5.3 // indirect
|
github.com/kelindar/bitmap v1.5.3 // indirect
|
||||||
github.com/kelindar/simd v1.1.2 // indirect
|
github.com/kelindar/simd v1.1.2 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -1,3 +1,5 @@
|
||||||
|
github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo=
|
||||||
|
github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc=
|
||||||
github.com/kelindar/bitmap v1.5.3 h1:/ty1SvbLE5ZKO4ToFNeXe3P3RrQsoj4a0x5gZNp5Vzo=
|
github.com/kelindar/bitmap v1.5.3 h1:/ty1SvbLE5ZKO4ToFNeXe3P3RrQsoj4a0x5gZNp5Vzo=
|
||||||
github.com/kelindar/bitmap v1.5.3/go.mod h1:j3qZjxH9s4OtvsnFTP2bmPkjqil9Y2xQlxPYHexasEA=
|
github.com/kelindar/bitmap v1.5.3/go.mod h1:j3qZjxH9s4OtvsnFTP2bmPkjqil9Y2xQlxPYHexasEA=
|
||||||
github.com/kelindar/simd v1.1.2 h1:KduKb+M9cMY2HIH8S/cdJyD+5n5EGgq+Aeeleos55To=
|
github.com/kelindar/simd v1.1.2 h1:KduKb+M9cMY2HIH8S/cdJyD+5n5EGgq+Aeeleos55To=
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue