namespace adventOfCode.day8; internal record Point(long X, long Y, long Z) { public static Point Parse(string line) { var tmp = line.Split(","); return new Point(int.Parse(tmp[0]), int.Parse(tmp[1]), int.Parse(tmp[2])); } public long Dist(Point p) { return (p.X - X) * (p.X - X) + (p.Y - Y) * (p.Y - Y) + (p.Z - Z) * (p.Z - Z); } } internal record PointPairs(Point P1, Point P2) : IComparable { public int CompareTo(PointPairs other) { return Dist().CompareTo(other.Dist()); } private long Dist() { return P1.Dist(P2); } } internal class Circuit : IComparable { private readonly ISet points; public Circuit() { points = new HashSet(); } public int CompareTo(Circuit other) { return Count().CompareTo(other.Count()); } public bool IsLinkedTo(Point point) { return points.Contains(point); } public void Add(Point point) { points.Add(point); } public int Count() { return points.Count(); } public bool IsLinkedTo(PointPairs pointPairs) { return IsLinkedTo(pointPairs.P1) || IsLinkedTo(pointPairs.P2); } public void Add(PointPairs pointPairs) { Add(pointPairs.P1); Add(pointPairs.P2); } public override string ToString() { var ret = ""; foreach (var p in points) ret += $"({p.X}, {p.Y}, {p.Z}), "; return ret; } public void AddAll(Circuit circuit) { foreach (var point in circuit.points) points.Add(point); } } internal class Circuits { private readonly List circuits; public Circuits() { circuits = new List(); } public void Add(PointPairs pointPairs) { var addedCircuits = new List(); foreach (var circuit in circuits) if (circuit.IsLinkedTo(pointPairs)) { circuit.Add(pointPairs); addedCircuits.Add(circuit); } if (addedCircuits.Count == 1) return; if (addedCircuits.Count < 1) { var newCircuit = new Circuit(); newCircuit.Add(pointPairs); circuits.Add(newCircuit); return; } var mergedCircuit = new Circuit(); foreach (var circuit in addedCircuits) { mergedCircuit.AddAll(circuit); circuits.Remove(circuit); } circuits.Add(mergedCircuit); } public List Get() { circuits.Sort(); circuits.Reverse(); return circuits; } public int Count() { return circuits.Count; } } public class Question { private static List parseInput(string input) { var lines = input.Split("\n"); var ret = new List(); foreach (var line in lines) ret.Add(Point.Parse(line)); return ret; } private static List CreateAllPointPairs(List points) { var ret = new List(); for (var i = 0; i < points.Count; i++) { var p = points[i]; for (var j = i + 1; j < points.Count; j++) ret.Add(new PointPairs(p, points[j])); } ret.Sort(); return ret; } private static Circuits CreateCircuits(List twoPointsList, int n) { var circuits = new Circuits(); var i = 0; foreach (var twoPoints in twoPointsList) { if (i >= n) break; circuits.Add(twoPoints); i++; } return circuits; } private static PointPairs? CreateOnBigCircuit(List twoPointsList, int total) { var circuits = new Circuits(); foreach (var twoPoints in twoPointsList) { circuits.Add(twoPoints); if (circuits.Count() == 1 && circuits.Get()[0].Count() == total) { return twoPoints; } } return null; } static long Question8A(string document, int n) { var points = parseInput(document); var twoPoints = CreateAllPointPairs(points); var circuits = CreateCircuits(twoPoints, n).Get(); return circuits[0].Count(); //* circuits[1].Count() * circuits[2].Count(); } static long Question8B(string document) { var points = parseInput(document); var twoPoints = CreateAllPointPairs(points); var circuits = CreateOnBigCircuit(twoPoints, points.Count); if (circuits == null) { return 0; } return circuits.P1.X * circuits.P2.X; } public static void Main_() { Console.WriteLine($"The answer to question 8a is {Question8A(Inputs.Input, 1_000)}" ); Console.WriteLine($"The answer to question 8b is {Question8B(Inputs.Input)}" ); } }