Skip to content

Commit 2793b04

Browse files
committed
Merge remote-tracking branch 'remotes/origin/DFS_performStep' into DFSmethods
2 parents 37b4783 + 96f9a8f commit 2793b04

File tree

7 files changed

+109
-91
lines changed

7 files changed

+109
-91
lines changed

src/main/java/com/google/hashcode/entity/Pizza.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,8 @@ public List<Cell> getCells() {
3737
* @param x - column number,0..max column number
3838
* @return a pizza cell with specified coordinated
3939
*/
40-
public Cell getCell(int y, int x) {
41-
final Optional<Cell> cellByCoordinates = cells.stream().filter(cell -> cell.x == x && cell.y == y).findFirst();
42-
if (cellByCoordinates.isPresent()) {
43-
return cellByCoordinates.get();
44-
} else throw new IllegalArgumentException("No cell with "
45-
+ "\n y: " + y
46-
+ "\nx: " + x);
40+
public Optional<Cell> getCell(int y, int x) {
41+
return cells.stream().filter(cell -> cell.x == x && cell.y == y).findFirst();
4742
}
4843

4944
public SliceInstruction getSliceInstruction() {
@@ -81,7 +76,11 @@ private String outputCellsArray() {
8176
//output rows coordinates
8277
stringBuilder.append(row).append(" ");
8378
for (int column = 0; column < columnsCount + 1; column++) {
84-
stringBuilder.append(this.getCell(row, column).toString()).append(" ");
79+
if (this.getCell(row, column).isPresent()) {
80+
stringBuilder.append(this.getCell(row, column).get().toString()).append(" ");
81+
} else {
82+
stringBuilder.append(" ").append(" ");
83+
}
8584
}
8685
stringBuilder.append("\n");
8786
}

src/main/java/com/google/hashcode/entity/Slice.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ public class Slice {
1919
public Slice() {
2020
}
2121

22-
public Slice(Cell cell) {
23-
this.cells = Collections.singletonList(cell);
22+
public Slice(Cell... cell) {
23+
this.cells = Arrays.asList(cell);
2424
}
2525

2626
public Slice(List<Cell> cells) {
@@ -110,7 +110,7 @@ public Slice generateStepDeltaBelow() {
110110
public Slice generateStepDeltaLeft() {
111111
List<Cell> delta = new ArrayList<>();
112112
for (int y = this.minY(); y <= this.maxY(); y++) {
113-
Cell cell = new Cell(y, minX() -1 , Ingredient.TOMATO);
113+
Cell cell = new Cell(y, minX() - 1, Ingredient.TOMATO);
114114
delta.add(cell);
115115
}
116116
LOGGER.info("generateStepDeltaLeft"

src/main/java/com/google/hashcode/entity/Step.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,21 @@
88
*/
99
public class Step {
1010

11-
public Step(Slice startPosition, Slice delta) {
12-
super();
13-
this.startPosition = startPosition;
14-
this.delta = delta;
15-
}
16-
17-
public Slice startPosition;
18-
11+
public Slice startPosition;
1912
public Slice delta;
2013

21-
@Override
22-
public String toString() {
23-
return "Step{" +
24-
"startPosition=" + startPosition +
25-
", delta=" + delta +
26-
'}';
27-
}
14+
public Step(Slice startPosition, Slice delta) {
15+
super();
16+
this.startPosition = startPosition;
17+
this.delta = delta;
18+
}
19+
20+
@Override
21+
public String toString() {
22+
return "Step{" +
23+
"startPosition=" + startPosition +
24+
", delta=" + delta +
25+
'}';
26+
}
2827

2928
}

src/main/java/com/google/hashcode/utils/DFSMethods.java

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
66

7-
import java.util.*;
7+
import java.util.ArrayList;
8+
import java.util.HashMap;
9+
import java.util.List;
10+
import java.util.Map;
811
import java.util.stream.Collectors;
912

1013
public abstract class DFSMethods {
@@ -13,44 +16,6 @@ public abstract class DFSMethods {
1316
private DFSMethods() {
1417
}
1518

16-
/**
17-
* Step as an entity is an amount of a pizza cells, that can be added to a slice of a pizza or a pizza cell.<br>
18-
* Step as an action is a process of:<br>
19-
* <p>
20-
* * adding cells to a start cell or a start slice<br>
21-
* * validate generated slice according to the pizza slicing instructions<br>
22-
* * if validation passed ->cutting the start cell with added cells from the pizza
23-
*
24-
* @param pizza (mutable) a pizza to perform step on
25-
* @param slice start position for a step
26-
* @return cutted slice from the pizza
27-
*/
28-
public static Optional<Slice> rightStep(Pizza pizza, Slice slice) {
29-
List<Cell> slicesRightBorder = slice.cells.stream()
30-
.filter(cell -> (cell.x == slice.maxX()) && (cell.y >= slice.minY()) && (cell.y <= slice.maxY()))
31-
.collect(Collectors.toList());
32-
//each cell should have a cell right side of it in the pizza
33-
try {
34-
Slice step = new Slice(slicesRightBorder.stream()
35-
.map(slicesRightBorderCell -> pizza.getCell(slicesRightBorderCell.y, slicesRightBorderCell.x + 1))
36-
.collect(Collectors.toList()));
37-
//check is step is valid
38-
Slice sliceAndStep = new Slice(new ArrayList<>(slice.cells));
39-
sliceAndStep.cells.addAll(step.cells);
40-
if (!slice.cells.isEmpty() && sliceAndStep.isValid(pizza)) {
41-
//remove the slice and step from the pizza
42-
pizza.getCells().removeAll(sliceAndStep.cells);
43-
return Optional.of(sliceAndStep);
44-
} else {
45-
return Optional.empty();
46-
}
47-
} catch (IllegalArgumentException e) {
48-
//if can't add at least one neccessary cell - > return an empty step
49-
LOGGER.info("Can't perform a step right !");
50-
return Optional.empty();
51-
}
52-
}
53-
5419
/**
5520
* For each slice find all available steps. We DON'T change the pizza on this stage
5621
*
@@ -79,13 +44,32 @@ public static Map<Slice, List<Step>> getAvailableSteps(Pizza pizza, List<Slice>
7944
return groupedSteps;
8045
}
8146

82-
public static Slice performStep(Pizza pizza, List<Step> steps) {
83-
//TODO pick-ups a step with a minimal steps number, execute it(cut it from the pizza, and a slice)
84-
return null;
47+
/**
48+
* Pick-ups a step with a minimal cells delta number,
49+
* execute it(cut it from the pizza, and add to a slice)
50+
*
51+
* @param pizza given pizza
52+
* @param steps available steps
53+
* @return formed slice that includes an original slice and delta from a step
54+
*/
55+
public static Slice performStep(Pizza pizza, Map<Slice, List<Step>> steps) {
56+
//1. Pick ups a steps list with minimal total cells number
57+
Step step = steps.values().stream().min((o1, o2) -> new StepsComparator().compare(o1, o2)).get().get(0);
58+
LOGGER.info("step to perform: " + step);
59+
//2. Cut all the step delta cells from pizza
60+
LOGGER.info("pizza before step: " + pizza
61+
+ "\ndelta to remove from the pizza: " + step.delta);
62+
pizza.getCells().removeAll(step.delta.cells);
63+
LOGGER.info("pizza after step:" + pizza);
64+
//3. Add the step cells to an output slice
65+
Slice slice = new Slice(step.delta.cells);
66+
slice.cells.addAll(step.startPosition.cells);
67+
return slice;
8568
}
8669

8770
/**
8871
* Finds a cells type with minimal cells numbers and generates one cell slices from them
72+
* Delete the slices from the pizza
8973
*
9074
* @param pizza given pizza
9175
* @return slices that are start positions for future slicing
@@ -100,15 +84,26 @@ public static List<Slice> cutAllStartPositions(Pizza pizza) {
10084
LOGGER.info("cutAllStartPositions for pizza: " + pizza
10185
+ "\nmushrooms number: " + mushrooms.size()
10286
+ "\ntomatoes number: " + tomatoes.size());
87+
List<Slice> startPositions = null;
10388
if (mushrooms.size() > tomatoes.size()) {
104-
return tomatoes.stream()
89+
startPositions = tomatoes.stream()
10590
.map(Slice::new)
10691
.collect(Collectors.toList());
92+
List<Cell> cellsToRemove = startPositions.stream()
93+
.flatMap(slice -> slice.cells.stream())
94+
.collect(Collectors.toList());
95+
pizza.getCells().removeAll(cellsToRemove);
10796
} else {
108-
return mushrooms.stream()
97+
startPositions = mushrooms.stream()
10998
.map(Slice::new)
11099
.collect(Collectors.toList());
100+
List<Cell> cellsToRemove = startPositions.stream()
101+
.flatMap(slice -> slice.cells.stream())
102+
.collect(Collectors.toList());
103+
pizza.getCells().removeAll(cellsToRemove);
111104
}
105+
LOGGER.info("pizza without start positions:" + pizza);
106+
return startPositions;
112107
}
113108

114109
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.google.hashcode.utils;
2+
3+
import com.google.hashcode.entity.Step;
4+
5+
import java.util.Comparator;
6+
import java.util.List;
7+
8+
/**
9+
* @author Grigoriy Lyashenko (Grog).
10+
*/
11+
public class StepsComparator implements Comparator<List<Step>> {
12+
13+
@Override
14+
public int compare(List<Step> o1, List<Step> o2) {
15+
long o1CellsCount = o1.stream()
16+
.flatMap(step -> step.delta.cells.stream())
17+
.count();
18+
long o2CellsCount = o2.stream()
19+
.flatMap(step -> step.delta.cells.stream())
20+
.count();
21+
return Long.compare(o1CellsCount, o2CellsCount);
22+
}
23+
}

src/test/java/com/google/hashcode/entity/PizzaTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66

77
import java.io.File;
88
import java.io.IOException;
9+
import java.util.Optional;
910

1011
import static com.google.hashcode.utils.InputFiles.EXAMPLE_INPUT_FILE_PATH;
1112
import static org.junit.Assert.assertEquals;
13+
import static org.junit.Assert.assertFalse;
1214

1315
/**
1416
* @author Grigoriy Lyashenko (Grog).
@@ -24,12 +26,13 @@ public void setup() throws IOException {
2426

2527
@Test
2628
public void getCell() throws Exception {
27-
assertEquals(examplePizza.getCell(0, 0), new Cell(0, 0, Ingredient.TOMATO));
29+
assertEquals(examplePizza.getCell(0, 0), Optional.of(new Cell(0, 0, Ingredient.TOMATO)));
2830
}
2931

30-
@Test(expected = IllegalArgumentException.class)
32+
@Test
3133
public void getCellException() throws Exception {
32-
examplePizza.getCell(100500, 0);
34+
Optional<Cell> cell = examplePizza.getCell(100500, 0);
35+
assertFalse(cell.isPresent());
3336
}
3437

3538
@Test
Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.google.hashcode.utils;
22

33
import com.google.hashcode.entity.*;
4+
import org.junit.Before;
45
import org.junit.Test;
56

67
import java.io.File;
78
import java.io.IOException;
8-
import java.util.ArrayList;
99
import java.util.Arrays;
1010
import java.util.List;
1111
import java.util.Map;
@@ -18,39 +18,38 @@
1818
*/
1919
public class DFSMethodsTest {
2020

21-
@Test
22-
public void rightStep() throws Exception {
23-
//Given a pizza
24-
Pizza pizza = new Pizza(new File(EXAMPLE_INPUT_FILE_PATH), IoUtils.parsePizza(EXAMPLE_INPUT_FILE_PATH), IoUtils.parseSliceInstructions(EXAMPLE_INPUT_FILE_PATH));
25-
//then perform a step right from a particular cell
26-
Slice actualSlice = DFSMethods.rightStep(pizza, new Slice(pizza.getCell(1, 3))).get();
27-
Slice expectedSlice = new Slice(Arrays.asList(new Cell(1, 3, Ingredient.MUSHROOM), new Cell(1, 4, Ingredient.TOMATO)));
28-
assertEquals(expectedSlice, actualSlice);
29-
//and slice has been removed from the pizza
30-
ArrayList<Cell> expectedPizzaCells = new ArrayList<>(pizza.getCells());
31-
expectedPizzaCells.removeAll(expectedSlice.cells);
32-
assertEquals(expectedPizzaCells, pizza.getCells());
21+
private Pizza pizza;
22+
23+
@Before
24+
public void setup() throws IOException {
25+
pizza = new Pizza(new File(EXAMPLE_INPUT_FILE_PATH), IoUtils.parsePizza(EXAMPLE_INPUT_FILE_PATH), IoUtils.parseSliceInstructions(EXAMPLE_INPUT_FILE_PATH));
3326
}
3427

3528
@Test
3629
public void getAvailableSteps() throws IOException {
37-
Pizza pizza = new Pizza(new File(EXAMPLE_INPUT_FILE_PATH), IoUtils.parsePizza(EXAMPLE_INPUT_FILE_PATH), IoUtils.parseSliceInstructions(EXAMPLE_INPUT_FILE_PATH));
3830
Map<Slice, List<Step>> actualMap = DFSMethods.getAvailableSteps(pizza, DFSMethods.cutAllStartPositions(pizza));
3931
assertEquals(3, actualMap.keySet().size());
40-
assertEquals(3, actualMap.get(new Slice(new Cell(1,1, Ingredient.MUSHROOM))).size());
41-
assertEquals(2, actualMap.get(new Slice(new Cell(1,2, Ingredient.MUSHROOM))).size());
42-
assertEquals(3, actualMap.get(new Slice(new Cell(1,3, Ingredient.MUSHROOM))).size());
32+
assertEquals(3, actualMap.get(new Slice(new Cell(1, 1, Ingredient.MUSHROOM))).size());
33+
assertEquals(2, actualMap.get(new Slice(new Cell(1, 2, Ingredient.MUSHROOM))).size());
34+
assertEquals(3, actualMap.get(new Slice(new Cell(1, 3, Ingredient.MUSHROOM))).size());
4335
}
4436

4537
@Test
4638
public void cutAllStartPositions() throws IOException {
47-
Pizza pizza = new Pizza(new File(EXAMPLE_INPUT_FILE_PATH), IoUtils.parsePizza(EXAMPLE_INPUT_FILE_PATH), IoUtils.parseSliceInstructions(EXAMPLE_INPUT_FILE_PATH));
4839
List<Slice> expected = Arrays.asList(
4940
new Slice(new Cell(1, 1, Ingredient.MUSHROOM)),
5041
new Slice(new Cell(1, 2, Ingredient.MUSHROOM)),
5142
new Slice(new Cell(1, 3, Ingredient.MUSHROOM))
5243
);
5344
assertEquals(expected, DFSMethods.cutAllStartPositions(pizza));
45+
assertEquals("We expect pizza size reduced to 15-3=12", 12, pizza.getCells().size());
5446
}
5547

48+
@Test
49+
public void performStep() {
50+
List<Slice> output = DFSMethods.cutAllStartPositions(pizza);
51+
Slice slice = DFSMethods.performStep(pizza, DFSMethods.getAvailableSteps(pizza, output));
52+
assertEquals(new Slice(Arrays.asList(new Cell(0, 2, Ingredient.TOMATO), new Cell(1, 2, Ingredient.MUSHROOM))), slice);
53+
assertEquals(11, pizza.getCells().size());
54+
}
5655
}

0 commit comments

Comments
 (0)