package main import ( "fmt" "math" "sort" "strings" "git.z1glr.de/advent-of-code-2025/pkg/aoc" ) type Point struct { X, Y, Z int Parent *Point Size int } func (p *Point) DistanceTo(p2 *Point) float64 { return math.Sqrt(float64((p.X-p2.X)*(p.X-p2.X) + (p.Y-p2.Y)*(p.Y-p2.Y) + (p.Z-p2.Z)*(p.Z-p2.Z))) } func (p *Point) GetRoot() *Point { if p.Parent == nil || p.Parent == p { return p } else { return p.GetRoot() } } func PointFromString(s string) Point { parts := strings.Split(s, ",") return Point{ X: aoc.ParseInt(parts[0]), Y: aoc.ParseInt(parts[1]), Z: aoc.ParseInt(parts[2]), Size: 1, } } type Connection struct { Length float64 P1, P2 *Point } func do(test bool) (int, int) { rows := aoc.ReadFileRows(test) points := make([]Point, len(rows)) for ii, rr := range rows { points[ii] = PointFromString(rr) } connections := []Connection{} for ii, p1 := range points { for _, p2 := range points[ii+1:] { connections = append(connections, Connection{ Length: p1.DistanceTo(&p2), P1: &p1, P2: &p2, }) } } // sort distances by length sort.Slice(connections, func(i, j int) bool { return connections[i].Length < connections[j].Length }) for _, cc := range connections[:10] { fmt.Println(*cc.P1) fmt.Println(*cc.P2) // if both have no parent, make the first one as the parent if cc.P1.Parent == nil && cc.P2.Parent == nil { cc.P1.Parent = cc.P1 cc.P2.Parent = cc.P1 cc.P1.Size++ // fmt.Println(cc.P2.GetRoot().Size) // if the second one has no parent, connect it to the first one } else if cc.P2.Parent == nil { cc.P2.Parent = cc.P1 cc.P1.GetRoot().Size++ } else if cc.P1.Parent == nil { cc.P1.Parent = cc.P2 cc.P2.GetRoot().Size++ // both have a parent -> make the parent of p2's root p1 } else { p2OldSize := cc.P2.GetRoot().Size cc.P2.GetRoot().Parent = cc.P1 cc.P1.GetRoot().Size += p2OldSize } } roots := []Point{} for _, pp := range points { if pp.GetRoot() == &pp { roots = append(roots, pp) } } sort.Slice(roots, func(i, j int) bool { return roots[i].Size < roots[j].Size }) res1 := roots[0].Size * roots[1].Size * roots[2].Size fmt.Println(res1) return res1, 0 } func main() { if r1, r2 := do(true); r1 == 40 && r2 == 0 { do(false) } }