using System.Text.RegularExpressions; namespace AdventOfCode.Solutions._2023 { public class Day11 : IChallange { public int Year => 2023; public int Day => 11; private readonly InputReader _inputReader; public Day11(InputReader inputReader) { _inputReader = inputReader; _inputReader.SetInput(this); } public async Task GetSolutionPart1() { string[] data = await _inputReader.ReadAsArrayString(); return CreateUniverseAndGetDistances(data).ToString(); } public async Task GetSolutionPart2() { string[] data = await _inputReader.ReadAsArrayString(); return CreateUniverseAndGetDistances(data, true).ToString(); } private long CreateUniverseAndGetDistances(string[] lineInput, bool part2 = false) { List 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 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; } } } }