Files
advent-of-code-2025/csharp/adventOfCode/day8/Main.cs
T
2026-01-02 12:01:29 -05:00

217 lines
4.9 KiB
C#

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<PointPairs>
{
public int CompareTo(PointPairs other)
{
return Dist().CompareTo(other.Dist());
}
private long Dist()
{
return P1.Dist(P2);
}
}
internal class Circuit : IComparable<Circuit>
{
private readonly ISet<Point> points;
public Circuit()
{
points = new HashSet<Point>();
}
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<Circuit> circuits;
public Circuits()
{
circuits = new List<Circuit>();
}
public void Add(PointPairs pointPairs)
{
var addedCircuits = new List<Circuit>();
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<Circuit> Get()
{
circuits.Sort();
circuits.Reverse();
return circuits;
}
public int Count()
{
return circuits.Count;
}
}
public class Question
{
private static List<Point> parseInput(string input)
{
var lines = input.Split("\n");
var ret = new List<Point>();
foreach (var line in lines) ret.Add(Point.Parse(line));
return ret;
}
private static List<PointPairs> CreateAllPointPairs(List<Point> points)
{
var ret = new List<PointPairs>();
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<PointPairs> 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<PointPairs> 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)}" );
}
}