Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,001 changes: 1,001 additions & 0 deletions 2017/practice/pizza/bfile.txt

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions 2017/practice/pizza/efile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
3 5 1 6
TTTTT
TMMMT
TTTTT
201 changes: 201 additions & 0 deletions 2017/practice/pizza/mfile.txt

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions 2017/practice/pizza/sfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
6 7 1 5
TMMMTTT
MMMMTMM
TTMTTMT
TMMTMMM
TTTTTTM
TTTTTTM
80 changes: 80 additions & 0 deletions 2017/practice/pizza/src/FileScannerReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import model.Cell;
import model.Pizza;


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class FileScannerReader {


private final static char TOMATO = 'T';


public Pizza read(String filePath) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line = br.readLine();
int i = 0;

Pizza result = new Pizza();

int countTomato = 0;

while (line != null) {
if (i == 0) {
String[] items = line.split(" ");
result.setMinIngredians(Integer.valueOf(items[2]));
result.setMaxSliceSize(Integer.valueOf(items[3]));
result.setRows(Integer.valueOf(items[0]));
result.setCollsAmount(Integer.valueOf(items[1]));

result.setCellsArr(new Cell[result.getRows()][result.getColls()]);
} else {
line = line.toUpperCase();

int rowIndex = i - 1;

Cell [] thisLine = new Cell[line.length()];
for (int j = 0; j < result.getColls(); j++) {
Cell cell = new Cell(TOMATO == line.charAt(j));

result.getCellsArr()[rowIndex][j] = cell;

if (cell.isTomato()) {
countTomato++;
}

cell.setColumn(j);
cell.setRow(rowIndex);
cell.setIndex(rowIndex*result.getColls()+j);
result.getCellsSet().add(cell);

if (rowIndex != 0) {
cell.setUp(result.getCellsArr()[rowIndex][j]);
result.getCellsArr()[rowIndex][j].setDown(cell);
}

if (j > 0) {
cell.setLeft(thisLine[j-1]);
thisLine[j-1].setRight(cell);
}

thisLine[j] = cell;
}
}

line = br.readLine();
i++;
}

int lessCount = Math.min(countTomato, result.getColls() * result.getRows() - countTomato);

result.setMaxSlicesCount(lessCount / result.getMinIngredians());

return result;

}

}
}
30 changes: 30 additions & 0 deletions 2017/practice/pizza/src/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import model.Pizza;
import model.Solution;
import out.FileResultDisplay;
import out.FrameResultsDisplay;

import java.io.IOException;

public class Main {

public static void main(String[] args) throws IOException {
Pizza inputData = new FileScannerReader().read("d:\\work\\@hashcode\\hashcode\\2017\\practice\\pizza\\bfile.txt");
Solution solution1 = getSolution(new OneWayPizzaBruteForceSolver(), inputData);
// Solution solution2 = getSolution(new TwoWayPizzaBruteForceSolver(), inputData);
int pizzaArea = inputData.getColls() * inputData.getRows();
System.out.println("Pizza area: " + pizzaArea);
new FileResultDisplay().display(inputData, solution1);
if (pizzaArea < 60000) {
System.out.println("Slices area: " + solution1.getSlices());
new FrameResultsDisplay().display(inputData, solution1);
}
System.out.println(inputData);
}

private static Solution getSolution(PizzaSolver pizzaSolver, Pizza inputData) {
Solution solution1 = pizzaSolver.getSolution(inputData);
System.out.println(pizzaSolver.getClass().getSimpleName() + " slices count: " + solution1.getSlices().size());
System.out.println(pizzaSolver.getClass().getSimpleName() + " slices area: " + solution1.slicesArea());
return solution1;
}
}
171 changes: 171 additions & 0 deletions 2017/practice/pizza/src/OneWayPizzaBruteForceSolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import model.Cell;
import model.Pizza;
import model.Slice;
import model.Solution;

import java.util.*;
import java.util.stream.Collectors;

public class OneWayPizzaBruteForceSolver implements PizzaSolver {

private int minIngredians = 0;
private int maxSliceSize = 0;

private int rows;
private int colls;

private TreeSet<Cell> cellsSet = new TreeSet<>();


private List<Slice> slices = new ArrayList<>();
private Solution bestSolution = null;

private Cell[][] cellsArr = null;

private int maxSlicesCount;
private int bestSlicesCount;
private int smallPeaceEnough;

private TreeSet<Solution> nextSolutions = new TreeSet<>((s1, s2) -> {
return Integer.compare(s2.slicesArea(), s1.slicesArea());
});

@Override
public Solution getSolution(Pizza pizza) {
init(pizza);

Solution solution = new Solution(rows, colls, new byte[rows * colls], new ArrayList<>(maxSlicesCount));
do {
solution = prepareSolution(solution);
if (isPerfectSolution(solution)) {
return solution;
}
if (isBetterThanBest(solution)) {
bestSolution = solution;
}

solution = nextSolutions.pollFirst();
} while (Objects.nonNull(solution));
return bestSolution;
}

private boolean isBetterThanBest(Solution solution) {
return Objects.isNull(bestSolution) || solution.slicesArea() > bestSolution.slicesArea();
}

private boolean isPerfectSolution(Solution solution) {
return solution.getSlices().size() == bestSlicesCount && solution.slicesArea() == rows * colls;
}

private Solution prepareSolution(Solution solution) {

int nextAvailableCellIndex;
while ((nextAvailableCellIndex = solution.getNextAvailableCell()) >= 0) {
Cell nextAvailable = cellsArr[nextAvailableCellIndex / colls][nextAvailableCellIndex % colls];
LinkedList<Slice> slices = getPossibleSlicesStartingAt(solution, nextAvailable);
Slice firstSlice = slices.pollFirst();
while (createMoreSolutions(solution) && !slices.isEmpty()) {
Solution newSol = solution.clone();
newSol.addSlice(slices.pollFirst());
nextSolutions.add(newSol);
}
if (firstSlice != null) {
solution.addSlice(firstSlice);
}
}
return solution;
}

private boolean createMoreSolutions(Solution solution) {
return solution.getFreeCellsCount() < smallPeaceEnough;
}

private LinkedList<Slice> getPossibleSlicesStartingAt(Solution solution, Cell start) {
LinkedList<Slice> slices = new LinkedList<>();
for (int width = maxSliceSize; width > 0; width--) {
for (int height = maxSliceSize; height > 0; height--) {
if (solution.isReverse()){
int temp = width;
width = height;
height = temp;
}
if (isValidBounds(solution, start, width, height) && hasValidIngredients(start, width, height)) {
slices.add(createSliceAt(start, width, height));
}
}
}
return slices;
}

private boolean isValidBounds(Solution solution, Cell start, int width, int height) {
if (width * height > maxSliceSize || start.getCol() + width > colls || start.getRow() + height > rows) {
return false;
}
for (int i = start.getCol(); i < start.getCol() + width; i++) {
for (int j = start.getRow(); j < start.getRow() + height; j++) {
if (!solution.isAvailableCell(cellsArr[j][i].getIndex())) {
return false;
}
}
}
return true;
}

private boolean hasValidIngredients(Cell start, int width, int height) {

int countT = 0;
int countM = 0;
for (int i = start.getCol(); i < start.getCol() + width; i++) {
for (int j = start.getRow(); j < start.getRow() + height; j++) {
if (cellsArr[j][i].isTomato()) {
countT++;
} else {
countM++;
}
if (countT >= minIngredians && countM >= minIngredians) {
return true;
}
}
}
return false;
}

private Slice createSliceAt(Cell start, int width, int height) {
List<Cell> sliceCells = new ArrayList<>();
for (int i = start.getCol(); i < start.getCol() + width; i++) {
for (int j = start.getRow(); j < start.getRow() + height; j++) {
sliceCells.add(cellsArr[j][i]);
}
}
return new Slice(sliceCells);
}

private void init(Pizza pizza) {
cellsArr = pizza.getCellsArr();
cellsSet = pizza.getCellsSet();
rows = pizza.getRows();
colls = pizza.getColls();
minIngredians = pizza.getMinIngredians();
maxSliceSize = pizza.getMaxSliceSize();
smallPeaceEnough = maxSliceSize*maxSliceSize*4;

Map<Boolean, List<Cell>> groupedIngredients = cellsSet.stream().collect(Collectors.groupingBy(Cell::isTomato));
Iterator<List<Cell>> iterator = groupedIngredients.values().iterator();
maxSlicesCount = rows * colls / minIngredians / 2;
bestSlicesCount = rows * colls / maxSliceSize;
if (rows * colls % maxSliceSize > 0) {
bestSlicesCount += 1;
}

while (iterator.hasNext()) {
List<Cell> next = iterator.next();
if (next.size() / minIngredians < maxSlicesCount) {
maxSlicesCount = next.size() / minIngredians;
}
}
if (bestSlicesCount > maxSlicesCount) {
bestSlicesCount = maxSlicesCount;
}
}

}
9 changes: 9 additions & 0 deletions 2017/practice/pizza/src/PizzaSolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import model.Pizza;
import model.Solution;

/**
* Created by mzobro on 2017-02-06.
*/
public interface PizzaSolver {
Solution getSolution(Pizza pizza);
}
Loading