Compare commits

..

No commits in common. "b4f03940e999d6d11145bc5e684df42e4fba3aa5" and "825f608c048dc2ac524976573a19e46346730a9e" have entirely different histories.

5 changed files with 0 additions and 1231 deletions

View file

@ -1,20 +0,0 @@
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

File diff suppressed because it is too large Load diff

View file

@ -1,208 +0,0 @@
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
View file

@ -3,7 +3,6 @@ module ballstads.name/aoc2025
go 1.25.5
require (
github.com/dominikbraun/graph v0.23.0 // indirect
github.com/kelindar/bitmap v1.5.3 // indirect
github.com/kelindar/simd v1.1.2 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect

2
go.sum
View file

@ -1,5 +1,3 @@
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/go.mod h1:j3qZjxH9s4OtvsnFTP2bmPkjqil9Y2xQlxPYHexasEA=
github.com/kelindar/simd v1.1.2 h1:KduKb+M9cMY2HIH8S/cdJyD+5n5EGgq+Aeeleos55To=