public IEnumerable <ArraySubblock> Chunkify(bool heavy) { if (this.Area == null) { this.Area = this.Sorter.Area; } var area = this.Area; var sorter = this.Sorter; while (true) { sorter.Sort(); if (sorter.IsAllEqual && sorter.IsAllTrue) { break; } //initialize program variables ChunkSolutionRect testsample = new ChunkSolutionRect() { Row = 0, Col = 0 }; var rowcount = sorter.RowCount; var colcount = sorter.ColumnCount; if (!sorter[0, 0]) { //full row scan, skim top if (tryFullRowsOfFalseOnTop(ref testsample, colcount)) { yield return(testsample.ToArraySubblock(sorter)); } //full column scan, skim side else if (tryFullColsOfFalseOnLeft(ref testsample, rowcount)) { yield return(testsample.ToArraySubblock(sorter)); } else { //look for biggest block testsample = getBiggestPossibleRectInUpperLeft(rowcount, colcount); yield return(testsample.ToArraySubblock(sorter)); } } else //sorter[0, 0] is true { //algorithm below, will actually work for sorter[0, 0] is false, but the above algorithm is much easier to understand //skim the top irregular shapes, bubbles in upper left //Stack<ChunkSolutionRect> solutions = new Stack<ChunkSolutionRect>(); //ChunkSolutionRect samplemax = default(ChunkSolutionRect); //var max = 0; //find first bubbles in top and left, set to startcol, startrow var startcol = getFirstFalseOnTopRow(colcount); var startrow = getFirstFalseOnLeftCol(rowcount); //run in parallel search for the first row or col with true int[] rowlen = null, collen = null; Parallel.For(0, 2, delegate(int branch) { if (branch == 1) { rowlen = getArrayOfFirstTrueInAllRowAfterCol(startcol, colcount, rowcount); } else { collen = getArrayOfFirstTrueInAllColumnAfterRow(startrow, colcount, rowcount); } }); //search for solutions in top bubble var lastsolution = default(ChunkSolutionRect); foreach (var solution in scanRowendingForSolutions(startcol, rowlen, rowcount).Reverse()) { lastsolution = solution; yield return(solution.ToArraySubblock(sorter)); } foreach (var solution in scanColendingForSolutions(startrow, collen, colcount, lastsolution, rowcount).Reverse()) { lastsolution = solution; yield return(solution.ToArraySubblock(sorter)); } //foreach (var solution in solutions.Reverse()) // yield return solution.ToArraySubblock(sorter); } } }