public bool AddFuelCell(FuelCell cell, bool updatePower = true)
        {
            if (IsFull)
            {
                if (updatePower)
                {
                    setTotalPower();
                }
                return(true);
            }

            Cluster.Add(cell);
            if (Cluster.Count > ClusterSize)
            {
                throw new ArgumentException();
            }
            if (Cluster.Count % ClusterSize == 0)
            {
                IsFull = true;
                if (updatePower)
                {
                    setTotalPower();
                }
                return(true);
            }

            return(false);
        }
        private void initGrid()
        {
            var length           = Grid.GetLength(0);
            var width            = Grid.GetLength(1);
            var finishedClusters = new List <FuelCellCluster>();

            for (var y = 0; y < Grid.GetLength(1); y++)
            {
                for (var x = 0; x < Grid.GetLength(0); x++)
                {
                    if (x + 2 < length && y + 2 < width)
                    {
                        var cluster = new FuelCellCluster();
                        var topLeft = new FuelCell(new Point(x + 1, y + 1), GridSerialNumber);
                        cluster.AddFuelCell(topLeft);
                        for (var i = 0; i < 3; i++)
                        {
                            for (var j = 0; j < 3; j++)
                            {
                                if (i == 0 && j == 0)
                                {
                                    continue;
                                }
                                cluster.AddFuelCell(new FuelCell(
                                                        new Point(topLeft.Coordinates.X + j, topLeft.Coordinates.Y + i), GridSerialNumber));
                            }
                        }

                        finishedClusters.Add(cluster);
                    }
                }
            }

            _fuelCellClusters = finishedClusters.OrderByDescending(x => x.TotalPower).ToList();
        }
Example #3
0
        public void ExampleFuelCells()
        {
            var point  = new Point(3, 5);
            var serial = 8;
            var cell   = new FuelCell(point, serial);

            var point2  = new Point(122, 79);
            var serial2 = 57;
            var cell2   = new FuelCell(point2, serial2);

            var point3  = new Point(217, 196);
            var serial3 = 39;
            var cell3   = new FuelCell(point3, serial3);


            var point4  = new Point(101, 153);
            var serial4 = 71;
            var cell4   = new FuelCell(point4, serial4);

            Console.WriteLine($"{cell.PowerLevel} | {cell2.PowerLevel} | {cell3.PowerLevel} | {cell4.PowerLevel}");
            Assert.Multiple(() =>
            {
                Assert.AreEqual(4, cell.PowerLevel);
                Assert.AreEqual(-5, cell2.PowerLevel);
                Assert.AreEqual(0, cell3.PowerLevel);
                Assert.AreEqual(4, cell4.PowerLevel);
            });
        }
 public FuelCellGrid(int serialNumber, bool partTwo = false)
 {
     GridSerialNumber  = serialNumber;
     Grid              = new FuelCell[300, 300];
     _fuelCellClusters = new List <FuelCellCluster>();
     if (!partTwo)
     {
         initGrid();
     }
     else
     {
         initGridPartTwo();
     }
 }
        /// <summary>
        ///     we can reuse the majority of the code from our original initGrid method, but now we need to expand each topLeft
        ///     node to its maximum size for each topLeft node we create.
        ///     This is probably gonna be hella slow.
        /// </summary>
        private void initGridPartTwo()
        {
            var length = Grid.GetLength(0);
            var width  = Grid.GetLength(1);

            for (var y = 0; y < width; y++)
            {
                for (var x = 0; x < length; x++)
                {
                    if (x < length && y < width)
                    {
                        var topLeft = new FuelCell(new Point(x + 1, y + 1), GridSerialNumber);
                        topLeft.MaxSizeIfTopLeft = x > y ? length - x : width - y;
                        Grid[x, y] = topLeft;
                    }
                }
            }

            var slimClusterBag = new ConcurrentBag <FuelCellClusterSlim>();

            var opt = new ParallelOptions();

            opt.MaxDegreeOfParallelism = 8;
            var count = 0;

            Parallel.For(0, width, opt, y =>
            {
                var rowMaxCluster = new FuelCellClusterSlim(0, new Point(0, 0), -1);
                for (var x = 0; x < length; x++)
                {
                    var currTopleft            = Grid[x, y];
                    var maxSize                = currTopleft.MaxSizeIfTopLeft;
                    var maxInitialized         = false;
                    var localTopLeftMaxCluster = new FuelCellClusterSlim(0, new Point(0, 0), -1);
                    for (var k = 0; k < maxSize; k++)
                    {
                        var power = 0;
                        for (var j = 0; j < k; j++)
                        {
                            for (var l = 0; l < k; l++)
                            {
                                power += Grid[x + l, y + j].PowerLevel;
                            }
                        }
                        if (!maxInitialized)
                        {
                            localTopLeftMaxCluster = new FuelCellClusterSlim(k,
                                                                             new Point(currTopleft.Coordinates.X, currTopleft.Coordinates.Y), power);
                            maxInitialized = true;
                        }
                        else if (localTopLeftMaxCluster.PowerLevel < power)
                        {
                            localTopLeftMaxCluster = new FuelCellClusterSlim(k,
                                                                             new Point(currTopleft.Coordinates.X, currTopleft.Coordinates.Y), power);
                        }
                    }

                    if (localTopLeftMaxCluster.PowerLevel > rowMaxCluster.PowerLevel)
                    {
                        rowMaxCluster = localTopLeftMaxCluster;
                    }
                }

                slimClusterBag.Add(rowMaxCluster);
                Interlocked.Increment(ref count);
                Console.WriteLine(count);
            });

            var slimClusterBagAsList = slimClusterBag.ToList();
            var testMax = slimClusterBagAsList.OrderByDescending(x => x.PowerLevel).First();
            var fcc     = new FuelCellCluster(testMax.ClusterSize);

            fcc.TotalPower = testMax.PowerLevel;
            fcc.AddFuelCell(new FuelCell(testMax.TopLeft, GridSerialNumber), false);
            _fuelCellClusters.Add(fcc);
        }