Day 13 optimized and fixed

This fixes my logic errors from the first attempt so the letters are much clearer now. It also swaps from trying to iterate over segments of a grid, pulling from later segments, to simply storing the list of marked points in a more efficient (and obviously smaller) collection that we add to and remove from when transforming points via folding, which is where the speedup comes from.

Fun fact: printing the result is about a quarter of the runtime of part 2.
This commit is contained in:
2021-12-13 08:48:37 -06:00
parent 4b9ff1c4bd
commit 4fc4bd2c20

155
src/13.cs
View File

@ -8,7 +8,7 @@ internal class Day13 : Day
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/13.txt");
int phase = 0;
var points = new List<(int, int)>();
var points = new HashSet<(int, int)>();
var folds = new List<(char, int)>();
foreach (var line in lines)
{
@ -29,145 +29,68 @@ internal class Day13 : Day
folds.Add((instruction[0].Last(), Convert.ToInt32(instruction[1])));
}
}
var grid = new bool[points.Max(x => x.Item1) + 1, points.Max(x => x.Item2) + 1];
foreach (var point in points)
{
grid[point.Item1, point.Item2] = true;
}
Part1(grid, folds);
Part2(grid, folds);
Part1(points, folds);
Part2(points, folds);
Logger.Log("");
}
private static void Part1(bool[,] grid, IEnumerable<(char, int)> folds)
private static void Fold(ICollection<(int x, int y)> points, char axis, int line)
{
using var t = new Timer();
int maxX = grid.GetLength(0);
int maxY = grid.GetLength(1);
foreach (var fold in folds)
if (axis == 'x')
{
for (int i = 0; i < grid.GetLength(0); i++)
points.Where(x => x.y > line).ToList().ForEach(x =>
{
for (int j = 0; j < grid.GetLength(1); j++)
{
var newX = i;
var newY = j;
if (fold.Item1 == 'y' && newX > fold.Item2)
{
newX = maxX - 1 - i;
}
if (fold.Item1 == 'x' && newY > fold.Item2)
{
newY = maxY - 1 - j;
}
if (grid[i,j])
{
grid[newX, newY] = grid[i, j];
}
}
}
if (fold.Item1 == 'x')
{
maxY -= fold.Item2 + 1;
}
else if (fold.Item1 == 'y')
{
maxX -= fold.Item2 + 1;
}
break;
points.Add((x.x, x.y - (x.y - line) * 2));
points.Remove(x);
});
}
int numDots = 0;
for (int i = 0; i < maxX; i++)
else
{
for (int j = 0; j < maxY; j++)
points.Where(x => x.x > line).ToList().ForEach(x =>
{
if (grid[i, j] == true)
{
numDots++;
}
}
points.Add((x.x - (x.x - line) * 2, x.y));
points.Remove(x);
});
}
Logger.Log($"part1: {numDots}");
}
private static void Part2(bool[,] grid, IEnumerable<(char, int)> folds)
private static void Part1(ICollection<(int x, int y)> grid, IList<(char axis, int line)> folds)
{
using var t = new Timer();
int maxX = grid.GetLength(0);
int maxY = grid.GetLength(1);
Fold(grid, folds[0].axis, folds[0].line);
for (int foldNum = 0; foldNum < folds.Count(); foldNum++)
Logger.Log($"part1: {grid.Count}");
}
private static void Part2(ICollection<(int x, int y)> grid, IList<(char axis, int line)> folds)
{
using var t = new Timer();
folds.Skip(1).ForEach(x => Fold(grid, x.axis, x.line));
int maxX = grid.Max(x => x.x);
int maxY = grid.Max(x => x.y);
var sb = new System.Text.StringBuilder();
for (int i = 0; i <= maxX; i++)
{
var fold = folds.ElementAt(foldNum);
if (foldNum > 0)
for (int j = 0; j <= maxY; j++)
{
var iStart = 0;
var jStart = 0;
if (fold.Item1 == 'x')
if (grid.Contains((i, j)))
{
jStart = fold.Item2 + 1;
}
if (fold.Item1 == 'y')
{
iStart = fold.Item2 + 1;
}
for (int i = iStart; i < maxX; i++)
{
for (int j = jStart; j < maxY; j++)
{
var newX = i;
var newY = j;
if (fold.Item1 == 'y' && newX > fold.Item2)
{
newX = maxX - 1 - i;
}
if (fold.Item1 == 'x' && newY > fold.Item2)
{
newY = maxY - 1 - j;
}
if (grid[i, j])
{
grid[newX, newY] = grid[i, j];
}
}
}
}
if (fold.Item1 == 'x')
{
maxY -= fold.Item2 + 1;
}
else if (fold.Item1 == 'y')
{
maxX -= fold.Item2 + 1;
}
}
int numDots = 0;
for (int i = 0; i < maxX; i++)
{
for (int j = 0; j < maxY; j++)
{
if (grid[i, j] == true)
{
Console.Write("#");
numDots++;
sb.Append('#');
}
else
{
Console.Write(".");
sb.Append('.');
}
}
Console.WriteLine();
if (i < maxX)
{
sb.Append('\n');
}
}
Logger.Log($"part2: {numDots}");
Logger.Log(sb.ToString());
Logger.Log($"part2: {grid.Count}");
}
}