100 lines
3.6 KiB
C#
100 lines
3.6 KiB
C#
using AdvenOfCode.Contracts;
|
|
using AdventOfCode.Extensions;
|
|
using AdventOfCode.HelperClasses;
|
|
|
|
namespace AoC_2025;
|
|
|
|
public class Day08 : IPuzzleSolver<long>
|
|
{
|
|
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<HashSet<Coordinate3d>> CreateCircuits(IEnumerable<Coordinate3d> jBoxes)
|
|
{
|
|
return jBoxes.Select(p => new HashSet<Coordinate3d> { p }).ToList();
|
|
}
|
|
|
|
private List<HashSet<Coordinate3d>> CombineCircuits(List<HashSet<Coordinate3d>> 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<HashSet<Coordinate3d>> 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<HashSet<Coordinate3d>> ConnectJBoxes(Coordinate3d a, Coordinate3d b, List<HashSet<Coordinate3d>> 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<Coordinate3d> 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<HashSet<Coordinate3d>> circuits, int amountMultiply)
|
|
{
|
|
return circuits
|
|
.Select(circuit => (long)circuit.Count)
|
|
.OrderDescending()
|
|
.Take(amountMultiply)
|
|
.Aggregate((acc, next) => acc * next);
|
|
}
|
|
} |