private List <PizzaSlice> PerformSlice_PhaseTwo(int[,] plate) { int nextSliceId = -1; Dictionary <int, PizzaSlice> sliceHash = new Dictionary <int, PizzaSlice>(); // Slice Pizza for (int r = 0; r < mRows; r++) { for (int c = 0; c < mColumns; c++) { if (SlicePizzaAtPosition(plate, r, c, sliceHash, nextSliceId) == true) { nextSliceId--; } } } // Try re-slicing List <PizzaSlice> slices = new List <PizzaSlice>(sliceHash.Values); foreach (PizzaSlice slice in slices) { PizzaSlice currentSlice = sliceHash[slice.ID]; sliceHash.Remove(currentSlice.ID); currentSlice.RestoreSliceToPlate(plate, mPlate); SlicePizzaAtPosition(plate, currentSlice.RowMin, currentSlice.ColumnMin, sliceHash, currentSlice.ID); } return(new List <PizzaSlice>(sliceHash.Values)); }
private bool SlicePizzaAtPosition(int[,] plate, int r, int c, Dictionary <int, PizzaSlice> sliceHash, int nextSliceId) { if (plate[r, c] < 0) { return(false); } PizzaSlice maxSlice = GetMaxSliceExtentionAt(plate, sliceHash, r, c, nextSliceId); if (maxSlice != null) { // Shrink existing slices Dictionary <int, int> sliceContent = maxSlice.GetSliceContent(plate); foreach (int overlapSliceId in sliceContent.Keys) { if (overlapSliceId > 0) { continue; } PizzaSlice existingSlice = sliceHash[overlapSliceId]; PizzaSlice existingAfterOverlap = existingSlice.BuildShirnkedSliceWithOverlapping(maxSlice); sliceHash[existingSlice.ID] = existingAfterOverlap; } maxSlice.RemoveSliceFromPlate(plate); sliceHash.Add(maxSlice.ID, maxSlice); return(true); } return(false); }
private PizzaSlice GetMaxSliceExtentionAt(int[,] plate, Dictionary <int, PizzaSlice> sliceHash, int row, int column, int nextSliceId) { PizzaSlice maxSlice = null; int maxSliceIngredients = 0; for (int minRow = row; minRow >= Math.Max(0, row - this.mMaxSliceSize); minRow--) { for (int maxRow = row; maxRow < Math.Min(row + this.mMaxSliceSize + 1, mRows); maxRow++) { for (int minCol = column; minCol >= Math.Max(0, column - this.mMaxSliceSize); minCol--) { for (int maxCol = column; maxCol < Math.Min(column + this.mMaxSliceSize + 1, mColumns); maxCol++) { int isValidSlice = IsValidSlice(this.mPlate, minRow, maxRow, minCol, maxCol); if ((isValidSlice == CHECK_SLICE_TOO_BIG) || (isValidSlice == CHECK_SLICE_INVALID_SLICE)) { break; } if (isValidSlice != CHECK_SLICE_VALID) { continue; } PizzaSlice newSlice = new PizzaSlice(nextSliceId, minRow, maxRow, minCol, maxCol); // The new slice contains positions previously not in any slice int newSliceIngredients = newSlice.CountIngredients(plate); if (newSliceIngredients == 0) { continue; } // Check overlapping slices are still valid slices Dictionary <int, int> sliceContent = newSlice.GetSliceContent(plate); bool isValidOverlap = true; foreach (int overlapSliceId in sliceContent.Keys) { if (overlapSliceId > 0) { continue; } PizzaSlice existingSlice = sliceHash[overlapSliceId]; PizzaSlice existingAfterOverlap = existingSlice.BuildShirnkedSliceWithOverlapping(newSlice); if (existingAfterOverlap == null) { isValidOverlap = false; break; } if (this.IsValidSlice(this.mPlate, existingAfterOverlap.RowMin, existingAfterOverlap.RowMax, existingAfterOverlap.ColumnMin, existingAfterOverlap.ColumnMax) != CHECK_SLICE_VALID) { isValidOverlap = false; break; } } if (isValidOverlap == false) { continue; } // Check if the new slice is bettter than existing max if (maxSlice == null) { maxSlice = newSlice; maxSliceIngredients = newSliceIngredients; } else if (maxSliceIngredients < newSliceIngredients) { maxSlice = newSlice; maxSliceIngredients = newSliceIngredients; } } } } } return(maxSlice); }
public PizzaSlice BuildShirnkedSliceWithOverlapping(PizzaSlice newSlice) { // Verify overlap is rect if ( // Partial column overlap ((newSlice.ColumnMin > this.ColumnMin) || (newSlice.ColumnMax < this.ColumnMax)) && // Partial row overlap ((newSlice.RowMin > this.RowMin) || (newSlice.RowMax < this.RowMax)) ) { return(null); } // Calc new overlapping slice int existingNewRowMin = this.RowMin; int existingNewRowMax = this.RowMax; int existingNewColumnMin = this.ColumnMin; int existingNewColumnMax = this.ColumnMax; // Full column overlap if ((newSlice.ColumnMin <= this.ColumnMin) && (newSlice.ColumnMax >= this.ColumnMax)) { // New slice in the middle of old slice if ((newSlice.RowMin > this.RowMin) && (newSlice.RowMax < this.RowMax)) { return(null); } // Above if (newSlice.RowMin <= this.RowMin) { existingNewRowMin = newSlice.RowMax + 1; } // Below if (newSlice.RowMax >= this.RowMax) { existingNewRowMax = newSlice.RowMin - 1; } } // Full row overlap if ((newSlice.RowMin <= this.RowMin) && (newSlice.RowMax >= this.RowMax)) { // New slice in the middle of old slice if ((newSlice.ColumnMin > this.ColumnMin) && (newSlice.ColumnMax < this.ColumnMax)) { return(null); } // Left if (newSlice.ColumnMin <= this.ColumnMin) { existingNewColumnMin = newSlice.ColumnMax + 1; } // Right if (newSlice.ColumnMax >= this.ColumnMax) { existingNewColumnMax = newSlice.ColumnMin - 1; } } if (existingNewColumnMin > existingNewColumnMax) { return(null); } if (existingNewRowMin > existingNewRowMax) { return(null); } return(new PizzaSlice(this.ID, existingNewRowMin, existingNewRowMax, existingNewColumnMin, existingNewColumnMax)); }