public static void Run() { long largestResult = long.MinValue; int largestSize = 0; var point = Point.Empty; history = new Dictionary <int, FuelCellAggregate[, ]>(); int input = 8141; FuelCellGridSize = new Size(300, 300); if (fuelCells == null) { fuelCells = new FuelCell[FuelCellGridSize.Width, FuelCellGridSize.Height]; var fuelCellAggregates = new FuelCellAggregate[FuelCellGridSize.Width, FuelCellGridSize.Height]; var perFuelCell = new Action <PerFuelCellDelegate>(dlgt => { for (int x = 1; x <= FuelCellGridSize.Width; x++) { for (int y = 1; y <= FuelCellGridSize.Height; y++) { if (fuelCells[x - 1, y - 1] == null) { fuelCells[x - 1, y - 1] = new FuelCell(); } dlgt?.Invoke(fuelCells[x - 1, y - 1], x, y); } } }); history.Add(1, new FuelCellAggregate[300, 300]); perFuelCell((cell, x, y) => { cell.Position = new Point(x, y); cell.RackId = x + 10; var powerLevel = CalculatePowerLevel(cell.RackId, y, input); cell.PowerLevel = powerLevel; history[1][x - 1, y - 1] = new FuelCellAggregate { PowerLevel = powerLevel }; }); } for (int size = 2; size <= 300; size++) { var result = RunOnce(size); if (result.PowerLevel > largestResult) { largestSize = size; largestResult = result.PowerLevel; point = result.Coordinate; } } Console.WriteLine($"{point.X},{point.Y},{largestSize}"); }
public static Result RunOnce(int pSize) { int previousSize = pSize - 1; var previousFuelCellAggregates = new FuelCellAggregate[0, 0]; if (history.ContainsKey(previousSize)) { previousFuelCellAggregates = history[previousSize]; } history.Add(pSize, new FuelCellAggregate[300 - pSize + 1, 300 - pSize + 1]); long largestPower = long.MinValue; var largestPoint = Point.Empty; for (int x = 0; x < FuelCellGridSize.Width - pSize + 1; x++) { for (int y = 0; y < FuelCellGridSize.Height - pSize + 1; y++) { long powerlevel = 0; for (int sy = 0; sy < pSize - 1; sy++) { var rightCell = fuelCells[x + pSize - 1, y + sy].PowerLevel; powerlevel += rightCell; } for (int sx = 0; sx < pSize - 1; sx++) { var bottomCell = fuelCells[x + sx, y + pSize - 1].PowerLevel; powerlevel += bottomCell; } // corner powerlevel += fuelCells[x + pSize - 1, y + pSize - 1].PowerLevel; powerlevel += history[previousSize][x, y].PowerLevel; if (powerlevel > largestPower) { largestPower = powerlevel; largestPoint = new Point(x, y); } history[pSize][x, y] = new FuelCellAggregate { PowerLevel = powerlevel }; } } return(new Result { Coordinate = new Point { X = largestPoint.X + 1, Y = largestPoint.Y + 1 }, PowerLevel = largestPower }); }
public static void Run() { int input = 8141; int testInput = 8; //input = testInput; FuelCellGridSize = new Size(300, 300); var fuelCells = new FuelCell[FuelCellGridSize.Width, FuelCellGridSize.Height]; var fuelCellAggregates = new FuelCellAggregate[FuelCellGridSize.Width, FuelCellGridSize.Height]; var perFuelCell = new Action <PerFuelCellDelegate>(dlgt => { for (int x = 1; x <= FuelCellGridSize.Width; x++) { for (int y = 1; y <= FuelCellGridSize.Height; y++) { dlgt?.Invoke(fuelCells[x - 1, y - 1], x, y); } } }); var perFuelCellAggregate = new Action <PerFuelCellAggregateDelegate>(dlgt => { for (int x = 0; x < FuelCellGridSize.Width; x++) { for (int y = 0; y < FuelCellGridSize.Height; y++) { dlgt?.Invoke(fuelCellAggregates[x, y], x, y); } } }); perFuelCell((cell, x, y) => { fuelCells[x - 1, y - 1] = new FuelCell(); }); perFuelCell((cell, x, y) => { cell.Position = new Point(x, y); cell.RackId = x + 10; var powerLevel = CalculatePowerLevel(cell.RackId, y, input); cell.PowerLevel = powerLevel; }); perFuelCellAggregate((cell, x, y) => { fuelCellAggregates[x, y] = new FuelCellAggregate(); }); for (int x = 0; x < FuelCellGridSize.Width - 2; x++) { for (int y = 0; y < FuelCellGridSize.Height - 2; y++) { for (int sx = 0; sx < 3; sx++) { for (int sy = 0; sy < 3; sy++) { fuelCellAggregates[x + 1, y + 1].PowerLevel = fuelCellAggregates[x + 1, y + 1].PowerLevel + fuelCells[x + sx, y + sy].PowerLevel; } } } } long largestPowerCellCenter = long.MinValue; var largestPowerCellTopLeft = Point.Empty; perFuelCellAggregate((cell, x, y) => { if (cell.PowerLevel > largestPowerCellCenter) { largestPowerCellCenter = cell.PowerLevel; largestPowerCellTopLeft = new Point(x - 1, y - 1); } }); Console.WriteLine($"Point X={largestPowerCellTopLeft.X+1}, Y={largestPowerCellTopLeft.Y+1}"); }