diff --git a/AdventOfCode/Common/AOCExtensions.cs b/AdventOfCode/Common/AOCExtensions.cs index f94411c..4b24299 100644 --- a/AdventOfCode/Common/AOCExtensions.cs +++ b/AdventOfCode/Common/AOCExtensions.cs @@ -57,5 +57,17 @@ namespace AdventOfCode.Common Console.WriteLine(); } } + + public static void PrintSquareArray(this string[,] arr) + { + for (int x = 0; x < arr.GetLength(0); x++) + { + for (int y = 0; y < arr.GetLength(1); y++) + { + Console.Write(arr[x, y] + " "); + } + Console.WriteLine(); + } + } } } diff --git a/AdventOfCode/_2023/Day11.cs b/AdventOfCode/_2023/Day11.cs new file mode 100644 index 0000000..c47e364 --- /dev/null +++ b/AdventOfCode/_2023/Day11.cs @@ -0,0 +1,144 @@ +using AdventOfCode.Models; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AdventOfCode._2023 +{ + public class Day11 : AOCDay + { + + protected override AOCResponse ExecutePartA() + { + return ExecutePartB(); + } + + protected override AOCResponse ExecutePartB() + { + //Determine how much space to replace each empty row with + var factor = this._request.Version == AOCVersion.A ? 2 : 1000000; + + //Create our universe + var superUniverse = new SuperDuperUniverseGalaxy(factor, this.GetSplitInput().ToList()); + + var galaxies = superUniverse.Galaxies; + + if (!this._request.IgnoreLogMessages) + { + foreach (var galaxy in galaxies) + { + Console.WriteLine($"Galaxy {galaxy.Id} is at {galaxy.X},{galaxy.Y}"); + } + } + + //Calculate the shortest path. + long total = 0; + for (int i = 0; i < galaxies.Count; i++) + { + for (int j = i + 1; j < galaxies.Count; j++) + { + total += galaxies[i].CalculateDistance(galaxies[j]); + } + } + this.Answer = total; + return this._response; + } + } + + //AKA Part B + class SuperDuperUniverseGalaxy + { + public List Galaxies { get; set; } + private string[,] _board; + public SuperDuperUniverseGalaxy(long factor, List input) + { + var rows = input.Count; + var columns = input.First().Length; + _board = new string[rows, columns]; + + for (int x = 0; x < rows; x++) + { + for (int y = 0; y < columns; y++) + { + _board[x, y] = input[x][y].ToString(); + } + } + + var doubledRows = GetDoubledRows(); + var doubledColumns = GetDoubledColumns(); + + Galaxies = new List(); + int galaxyCount = 0; + for (int x = 0; x < _board.GetLength(0); x++) + { + for (int y = 0; y < _board.GetLength(1); y++) + { + if (_board[x, y].Equals("#")) + { + long xOffset = doubledRows.Count(dR => dR <= x); + long yOffset = doubledColumns.Count(dC => dC <= y); + Galaxies.Add(new Galaxy() + { + Id = (++galaxyCount).ToString(), + X = (xOffset * factor) + x - xOffset, + Y = (yOffset * factor) + y - yOffset + }); + } + } + } + } + + public List GetDoubledRows() + { + var doubledRows = new List(); + for (int x = 0; x < _board.GetLength(0); x++) + { + bool isEmpty = true; + for (int y = 0; y < _board.GetLength(1); y++) + { + if (_board[x, y] == "#") + { + isEmpty = false; + break; + } + } + if (isEmpty) + doubledRows.Add(x); + } + return doubledRows; + } + + public List GetDoubledColumns() + { + var doubledColumns = new List(); + for (int y = 0; y < _board.GetLength(1); y++) + { + bool isEmpty = true; + for (int x = 0; x < _board.GetLength(0); x++) + { + if (_board[x, y] == "#") + { + isEmpty = false; + break; + } + } + if (isEmpty) + doubledColumns.Add(y); + } + return doubledColumns; + } + } + + class Galaxy + { + public string Id { get; set; } + public long X { get; set; } + public long Y { get; set; } + + public long CalculateDistance(Galaxy galaxy) + { + //We use Manhattan distance |x2 - x1| + |y2-y1| + return Math.Abs(this.X - galaxy.X) + Math.Abs(this.Y - galaxy.Y); + } + } +}