package main import ( "bufio" "fmt" "math" "os" "slices" "sort" "strconv" "strings" ) func main(){ fmt.Println("Advent of Code 2025 - Day 8 - Part 1") f,_:=os.Open("8/input") defer f.Close() var junction_boxes [][]int64 scanner := bufio.NewScanner(f) for scanner.Scan(){ line := scanner.Text() var coords []int64 for c := range strings.SplitSeq(line, ","){ c_i,_ := strconv.ParseInt(c,10,64) coords = append(coords, c_i) } junction_boxes = append(junction_boxes, coords) } distances := calculate_distances(junction_boxes) top3_circuits := create_circuits(1000, distances)[:3] res := 1 for _,c := range top3_circuits{ res *= c } fmt.Println(res) } func create_circuits(nb_connections int, distances sj_box_distances) []int { var circuits [][]int circuits = append(circuits, []int{distances[0].b1, distances[0].b2}) for i := 1; i < nb_connections; i++ { b1,b2 := distances[i].b1, distances[i].b2 new := true for cir := range circuits { ok1, ok2 := slices.Contains(circuits[cir],b1), slices.Contains(circuits[cir],b2) if ok1 && ok2 { new = false break } else if ok1 && !ok2 { new = false merge_circuits(cir, b2, &circuits) break } else if !ok1 && ok2 { new = false merge_circuits(cir, b1, &circuits) break } } if new { circuits = append(circuits, []int{b1,b2}) } } var res []int for _,c := range circuits{ res = append(res, len(c)) } sort.Sort(sort.Reverse(sort.IntSlice(res))) return res } func merge_circuits(idx_cir, box int, circuits* [][]int) { idx_cir_tomerge := -1 for i := range *circuits{ if slices.Contains((*circuits)[i],box){ idx_cir_tomerge = i } } if idx_cir_tomerge >= 0 { (*circuits)[idx_cir] = append((*circuits)[idx_cir], (*circuits)[idx_cir_tomerge]...) (*circuits)[idx_cir_tomerge] = (*circuits)[len(*circuits)-1] (*circuits) = (*circuits)[:len(*circuits)-1] } else { (*circuits)[idx_cir] = append((*circuits)[idx_cir], box) } } type j_box_distance struct { b1,b2 int dis float64 } type sj_box_distances []j_box_distance func (a sj_box_distances) Len() int { return len(a)} func (a sj_box_distances) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a sj_box_distances) Less(i, j int) bool { return a[i].dis < a[j].dis } func calculate_distances(points [][]int64) sj_box_distances { var res sj_box_distances for i := range(points) { for j := i+1; j < len(points); j++{ b1,b2 := i,j dis := euclidiean_distance(points[i],points[j]) res = append(res, j_box_distance{b1,b2,dis}) } } sort.Sort(res) return res } func euclidiean_distance(p1, p2 []int64) float64 { dx,dy,dz := math.Pow(float64(p1[0] - p2[0]), 2.0), math.Pow(float64(p1[1] - p2[1]), 2.0), math.Pow(float64(p1[2] - p2[2]), 2.0) return math.Sqrt(dx + dy + dz) }