217 lines
4.9 KiB
C#
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)}" );
|
|
|
|
}
|
|
} |