AdventOfCode/AoC_2025/Day08.cs

119 lines
4.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IO;
using System.Linq;
using AdvenOfCode.Contracts;
using Coordinate = (long x, long y, long z);
namespace AoC_2025;
public class Day08 : IPuzzleSolver<long>
{
private readonly int _amountToConnect;
public Day08(int amountToConnect)
{
_amountToConnect = amountToConnect;
}
private Coordinate[] 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 => (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<Coordinate>> CreateCircuits(IEnumerable<Coordinate> jBoxes)
{
return jBoxes.Select(p => new HashSet<Coordinate> { p }).ToList();
}
private List<HashSet<Coordinate>> CombineCircuits(List<HashSet<Coordinate>> circuits,
IEnumerable<(Coordinate boxA, Coordinate boxB)> jBoxPairs, int amountToConnect)
{
circuits = jBoxPairs
.Take(amountToConnect)
.Aggregate(circuits, (acc, next) => ConnectJBoxes(next.boxA, next.boxB, acc));
return circuits;
}
private (Coordinate a, Coordinate b) LastCombinedConnectAllCircuits(List<HashSet<Coordinate>> circuits,
IEnumerable<(Coordinate boxA, Coordinate boxB)> jBoxPairs)
{
foreach (var jBoxPair in jBoxPairs)
{
circuits = ConnectJBoxes(jBoxPair.boxA, jBoxPair.boxB, circuits);
if(circuits.Count <= 1)
return jBoxPair;
}
return ((0,0,0), (0,0,0));
}
private long GetDistance(Coordinate a, Coordinate b)
{
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z);
}
private List<HashSet<Coordinate>> ConnectJBoxes(Coordinate a, Coordinate b, List<HashSet<Coordinate>> 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<(Coordinate boxA, Coordinate boxB)> GetAllCombinationsSortedByDistance(IEnumerable<Coordinate> jBoxes)
{
var combinations = Combinations(jBoxes)
.OrderBy(x => GetDistance(x.a, x.b));
return combinations;
}
private IEnumerable<(TValue a, TValue b)> Combinations<TValue>(IEnumerable<TValue> values)
{
var enumeratedValues = values.Index().ToArray();
var pairs =
from a in enumeratedValues
from b in enumeratedValues
where a.Index < b.Index
select (a.Item, b.Item);
return pairs;
}
private long MultiplyLargestCircuitLength(List<HashSet<Coordinate>> circuits, int amountMultiply)
{
return circuits
.Select(circuit => (long)circuit.Count)
.OrderDescending()
.Take(amountMultiply)
.Aggregate((acc, next) => acc * next);
}
}