using AdvenOfCode.Contracts; using AdventOfCode.Extensions; using AdventOfCode.HelperClasses; namespace AoC_2025; public class Day08 : IPuzzleSolver { private readonly int _amountToConnect; public Day08(int amountToConnect) { _amountToConnect = amountToConnect; } private Coordinate3d[] ParsePuzzleInput(string path) { var puzzleInput = File.ReadAllLines(path) .Where(line => !string.IsNullOrWhiteSpace(line)) .Select(line => line.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(str => long.Parse(str)).ToArray()) .Select(numbers => new Coordinate3d(numbers[0], numbers[1], numbers[2])) .ToArray(); return puzzleInput; } public long SolvePart1(string pathToPuzzleInput) { var jBoxes = ParsePuzzleInput(pathToPuzzleInput); var jBoxPairs = GetAllCombinationsSortedByDistance(jBoxes); var circuits = CreateCircuits(jBoxes); circuits = CombineCircuits(circuits, jBoxPairs, _amountToConnect); var checksum = MultiplyLargestCircuitLength(circuits, 3); return checksum; } public long SolvePart2(string pathToPuzzleInput) { var jBoxes = ParsePuzzleInput(pathToPuzzleInput); var jBoxPairs = GetAllCombinationsSortedByDistance(jBoxes); var circuits = CreateCircuits(jBoxes); var lastConnected = LastCombinedConnectAllCircuits(circuits, jBoxPairs); return lastConnected.a.X * lastConnected.b.X; } private List> CreateCircuits(IEnumerable jBoxes) { return jBoxes.Select(p => new HashSet { p }).ToList(); } private List> CombineCircuits(List> circuits, IEnumerable<(Coordinate3d boxA, Coordinate3d boxB)> jBoxPairs, int amountToConnect) { circuits = jBoxPairs .Take(amountToConnect) .Aggregate(circuits, (acc, next) => ConnectJBoxes(next.boxA, next.boxB, acc)); return circuits; } private (Coordinate3d a, Coordinate3d b) LastCombinedConnectAllCircuits(List> circuits, IEnumerable<(Coordinate3d boxA, Coordinate3d boxB)> jBoxPairs) { foreach (var jBoxPair in jBoxPairs) { circuits = ConnectJBoxes(jBoxPair.boxA, jBoxPair.boxB, circuits); if(circuits.Count <= 1) return jBoxPair; } return (new(0,0,0), new(0,0,0)); } private List> ConnectJBoxes(Coordinate3d a, Coordinate3d b, List> circuits) { var circuitToAddBTo = circuits.First(circuit => circuit.Contains(a)); var circuitToAddATo = circuits.First(circuit => circuit.Contains(b)); if (circuitToAddATo == circuitToAddBTo) { return circuits; } circuitToAddBTo.UnionWith(circuitToAddATo); circuits.Remove(circuitToAddATo); return circuits; } private IEnumerable<(Coordinate3d boxA, Coordinate3d boxB)> GetAllCombinationsSortedByDistance(IEnumerable jBoxes) { var combinations = jBoxes.Combinations(2) .Select(x => (a: x[0], b: x[1])) .OrderBy(x => Coordinate3d.GetEuclidianDistance(x.a, x.b)); return combinations; } private long MultiplyLargestCircuitLength(List> circuits, int amountMultiply) { return circuits .Select(circuit => (long)circuit.Count) .OrderDescending() .Take(amountMultiply) .Aggregate((acc, next) => acc * next); } }