From 4a9a949d1ef28792e6066fbd60eff24d4f998d36 Mon Sep 17 00:00:00 2001 From: Alexander Sigler Date: Mon, 11 Dec 2023 17:55:27 -0800 Subject: [PATCH] Completed Day 11 with optimized solution (no more giant 2d array) --- AdventOfCode/Common/AOCExtensions.cs | 12 +++ AdventOfCode/_2023/Day11.cs | 121 +++++++++++++++++++++------ 2 files changed, 109 insertions(+), 24 deletions(-) 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 index fac36ac..c47e364 100644 --- a/AdventOfCode/_2023/Day11.cs +++ b/AdventOfCode/_2023/Day11.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; namespace AdventOfCode._2023 { @@ -11,61 +10,135 @@ namespace AdventOfCode._2023 protected override AOCResponse ExecutePartA() { - - return this._response; + 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; } } - class UniverseGalaxy + //AKA Part B + class SuperDuperUniverseGalaxy { + public List Galaxies { get; set; } private string[,] _board; - public UniverseGalaxy(List input) + public SuperDuperUniverseGalaxy(long factor, List input) { var rows = input.Count; var columns = input.First().Length; _board = new string[rows, columns]; - for (int y = 0; y < rows; y++) + for (int x = 0; x < rows; x++) { - for (int x = 0; x < columns; x++) + for (int y = 0; y < columns; y++) { _board[x, y] = input[x][y].ToString(); } } - //TODO Double the board + var doubledRows = GetDoubledRows(); + var doubledColumns = GetDoubledColumns(); - //TODO Find all the galaxies on the board + 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 + }); + } + } + } + } - //TODO Calculate the distance between all of the galaxies + 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; + } - //TODO Find the shortest distance between them! + 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 Dictionary DistanceLookup { get; set; } public string Id { get; set; } - public int X { get; set; } - public int Y { get; set; } + public long X { get; set; } + public long Y { get; set; } - public void CalculateDistance(IEnumerable galaxies) + public long CalculateDistance(Galaxy galaxy) { - DistanceLookup = new Dictionary(); - foreach (var galaxy in galaxies) - { - if (galaxy.Id.Equals(this.Id)) continue; - - long distanceBetweenGalaxies = -1; //TODO need to calculate this? some math.min and math.max - DistanceLookup[galaxy.Id] = distanceBetweenGalaxies; - } + //We use Manhattan distance |x2 - x1| + |y2-y1| + return Math.Abs(this.X - galaxy.X) + Math.Abs(this.Y - galaxy.Y); } } }