AdventOfCode/AdventOfCode.Solutions/2023/Day 11/Day11.cs
2024-12-01 10:17:24 +01:00

94 lines
3.3 KiB
C#

using AdventOfCode.Core.Shared.IO;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public class Day11 : IChallange
{
public int Year => 2023;
public int Day => 11;
private readonly IInputReader _inputReader;
public Day11(IInputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
string[] data = await _inputReader.ReadAsArrayString();
return CreateUniverseAndGetDistances(data).ToString();
}
public async Task<string> GetSolutionPart2()
{
string[] data = await _inputReader.ReadAsArrayString();
return CreateUniverseAndGetDistances(data, true).ToString();
}
private long CreateUniverseAndGetDistances(string[] lineInput, bool part2 = false)
{
List<int> columns = []; // the list of indexes where expation takes place
for (int columnIndex = 0; columnIndex < lineInput[0].Length; columnIndex++)
{
if(lineInput.Select(line => line[columnIndex]).All(c => c == '.'))
{
columns.Add(columnIndex);
}
}
List<Galaxy> galaxies = [];
int rowsAdded = 0; // the rows where expation takes place
for (int rowIndex = 0; rowIndex < lineInput.Length; rowIndex++)
{
if (lineInput[rowIndex].All(c => c == '.'))
{
rowsAdded++; // add and continue
continue;
}
foreach (Match galaxyMatch in Regex.Matches(lineInput[rowIndex], @"#"))
{
int columnExpantion = columns.Where(c => c < galaxyMatch.Index).Count();
Galaxy newGalaxy = new(rowIndex, galaxyMatch.Index, columnExpantion, rowsAdded);
galaxies.Add(newGalaxy);
}
}
long total = 0;
for (int galaxiesIndex = 0; galaxiesIndex < galaxies.Count - 1; galaxiesIndex++)
{
total += galaxies
.Where(g => galaxies.IndexOf(g) > galaxiesIndex) // only take the next ones, skip all prev ones
.Select(g =>
galaxies[galaxiesIndex].GetManhattanDistance(g) + // get the distance
galaxies[galaxiesIndex].GetExpantionsDistance(g, part2) // get the expantion distance
)
.Sum();
}
return total;
}
private class Galaxy(int x, int y, int xExpantion, int yExpantion) : Node(x, y, '#')
{
public int HorizonalExpantions { get; set; } = xExpantion;
public int VerticalExpantions { get; set; } = yExpantion;
public long GetExpantionsDistance(Galaxy other, bool part2 = false)
{
int times = Math.Abs(HorizonalExpantions - other.HorizonalExpantions) + Math.Abs(VerticalExpantions - other.VerticalExpantions);
if (part2)
{
return (times * 1_000_000) - times;
}
return times;
}
}
}
}