|
|
@ -1,144 +0,0 @@
|
|
|
|
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<Galaxy> Galaxies { get; set; }
|
|
|
|
|
|
|
|
private string[,] _board;
|
|
|
|
|
|
|
|
public SuperDuperUniverseGalaxy(long factor, List<string> 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<Galaxy>();
|
|
|
|
|
|
|
|
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<int> GetDoubledRows()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var doubledRows = new List<int>();
|
|
|
|
|
|
|
|
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<int> GetDoubledColumns()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var doubledColumns = new List<int>();
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|