171 lines
4.2 KiB
C#
171 lines
4.2 KiB
C#
using System.Diagnostics;
|
|
|
|
namespace CosmicExpansion;
|
|
|
|
public class Program
|
|
{
|
|
public static async Task<int> Main(string[] args)
|
|
{
|
|
if (args.Length is 0)
|
|
{
|
|
Console.WriteLine("Please provide a path to the input file.");
|
|
return -1;
|
|
}
|
|
|
|
if (File.Exists(args[0]) is false)
|
|
{
|
|
Console.WriteLine("The provided file does not exist.");
|
|
return -2;
|
|
}
|
|
|
|
var isPart2 = args.Length > 1 && args[1] == "part2";
|
|
var input = await File.ReadAllLinesAsync(args[0]);
|
|
|
|
var stopwatch = new Stopwatch();
|
|
stopwatch.Start();
|
|
|
|
var universe = isPart2
|
|
? Universe.Parse(input, 1_000_000)
|
|
: Universe.Parse(input);
|
|
|
|
var result = universe.SumOfShortestPathsBetweenGalaxies;
|
|
|
|
stopwatch.Stop();
|
|
|
|
Console.WriteLine($"The sum of the shortest paths between galaxies is {result}. ({stopwatch.ElapsedMilliseconds}ms)");
|
|
|
|
return (int)result;
|
|
}
|
|
}
|
|
|
|
public class Universe(
|
|
int height,
|
|
int width,
|
|
List<Galaxy> galaxies
|
|
)
|
|
{
|
|
private const char GalaxySymbol = '#';
|
|
public int Height { get; init; } = height;
|
|
public int Width { get; init; } = width;
|
|
public List<Galaxy> Galaxies { get; init; } = galaxies;
|
|
public long SumOfShortestPathsBetweenGalaxies =>
|
|
GetShortestPathsBetweenGalaxies()
|
|
.Values
|
|
.Sum();
|
|
|
|
public Dictionary<(int galaxyOneIndex, int galaxyTwoIndex), long> GetShortestPathsBetweenGalaxies()
|
|
{
|
|
var shortestPaths = new Dictionary<(int galaxyOneIndex, int galaxyTwoIndex), long>();
|
|
|
|
for (int i = 0; i < Galaxies.Count; i++)
|
|
{
|
|
var galaxyOne = Galaxies[i];
|
|
|
|
for (int j = i + 1; j < Galaxies.Count; j++)
|
|
{
|
|
var galaxyTwo = Galaxies[j];
|
|
|
|
if (shortestPaths.ContainsKey((i, j)) || shortestPaths.ContainsKey((j, i)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var shortestPath = CalculateDistanceBetweenGalaxies(galaxyOne, galaxyTwo);
|
|
shortestPaths.Add((i, j), shortestPath);
|
|
}
|
|
}
|
|
|
|
return shortestPaths;
|
|
}
|
|
|
|
public static long CalculateDistanceBetweenGalaxies(Galaxy galaxyOne, Galaxy galaxyTwo) =>
|
|
Math.Abs(galaxyTwo.Row - galaxyOne.Row) + Math.Abs(galaxyTwo.Column - galaxyOne.Column);
|
|
|
|
public static Universe Parse(string[] input, int expandFactor = 2)
|
|
{
|
|
var emptyRows = new List<int>();
|
|
var emptyColumns = new List<int>();
|
|
var galaxies = new List<Galaxy>();
|
|
|
|
for (int i = 0; i < input.Length; i++)
|
|
{
|
|
var currentRow = input[i];
|
|
|
|
if (currentRow.Contains(GalaxySymbol) is false)
|
|
{
|
|
emptyRows.Add(i);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < input[0].Length; i++)
|
|
{
|
|
var galaxyInColumn = false;
|
|
|
|
for (int j = 0; j < input.Length; j++)
|
|
{
|
|
var currentPosition = input[j][i];
|
|
|
|
if (currentPosition == GalaxySymbol)
|
|
{
|
|
galaxyInColumn = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (galaxyInColumn is false)
|
|
{
|
|
emptyColumns.Add(i);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < input.Length; i++)
|
|
{
|
|
var currentRow = input[i];
|
|
|
|
for (int j = 0; j < currentRow.Length; j++)
|
|
{
|
|
var currentPosition = currentRow[j];
|
|
|
|
if (currentPosition == GalaxySymbol)
|
|
{
|
|
var numOfEmptyRowsBefore = emptyRows.Where(row => row < i).Count();
|
|
var rowOffset = numOfEmptyRowsBefore is 0
|
|
? 0
|
|
: (numOfEmptyRowsBefore * expandFactor) - numOfEmptyRowsBefore;
|
|
|
|
var numOfEmptyColumnsBefore = emptyColumns.Where(column => column < j).Count();
|
|
var columnOffset = numOfEmptyColumnsBefore is 0
|
|
? 0
|
|
: (numOfEmptyColumnsBefore * expandFactor) - numOfEmptyColumnsBefore;
|
|
|
|
galaxies.Add(new Galaxy(i + rowOffset, j + columnOffset));
|
|
}
|
|
}
|
|
}
|
|
|
|
var heightOffset = emptyRows.Count is 0
|
|
? 0
|
|
: (emptyRows.Count * expandFactor) - emptyRows.Count;
|
|
var widthOffset = emptyColumns.Count is 0
|
|
? 0
|
|
: (emptyColumns.Count * expandFactor) - emptyColumns.Count;
|
|
|
|
var height = input.Length + heightOffset;
|
|
var width = input[0].Length + widthOffset;
|
|
|
|
return new Universe(
|
|
height,
|
|
width,
|
|
galaxies
|
|
);
|
|
}
|
|
}
|
|
|
|
public class Galaxy(
|
|
long row,
|
|
long column
|
|
)
|
|
{
|
|
public long Row { get; init; } = row;
|
|
public long Column { get; init; } = column;
|
|
} |