ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# JuanMa's solution

## to Rectangles in the Java Track

Published at Jan 04 2021 · 0 comments
Instructions
Test suite
Solution

Count the rectangles in an ASCII diagram like the one below.

``````   +--+
++  |
+-++--+
|  |  |
+--+--+
``````

The above diagram contains 6 rectangles:

``````

+-----+
|     |
+-----+
``````
``````   +--+
|  |
|  |
|  |
+--+
``````
``````   +--+
|  |
+--+

``````
``````

+--+
|  |
+--+
``````
``````

+--+
|  |
+--+
``````
``````
++
++

``````

You may assume that the input is always a proper rectangle (i.e. the length of every line equals the length of the first line).

## Setup

Go through the setup instructions for Java to install the necessary dependencies:

https://exercism.io/tracks/java/installation

# Running the tests

You can run all the tests for an exercise by entering the following in your terminal:

``````\$ gradle test
``````

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by removing the `@Ignore("Remove to run test")` annotation.

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### RectangleCounterTest.java

``````import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class RectangleCounterTest {

private RectangleCounter rectangleCounter;

@Before
public void setUp() {
rectangleCounter = new RectangleCounter();
}

@Test
public void testInputWithNoRowsContainsNoRectangles() {
String[] inputGrid = new String[]{};

assertEquals(0, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testInputWithNoColumnsContainsNoRectangles() {
String[] inputGrid = new String[]{""};

assertEquals(0, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testNonTrivialInputWithNoRectangles() {
String[] inputGrid = new String[]{" "};

assertEquals(0, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testInputWithOneRectangle() {
String[] inputGrid = new String[]{
"+-+",
"| |",
"+-+"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testInputWithTwoRectanglesWithoutSharedEdges() {
String[] inputGrid = new String[]{
"  +-+",
"  | |",
"+-+-+",
"| |  ",
"+-+  "
};

assertEquals(2, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testInputWithFiveRectanglesWithSharedEdges() {
String[] inputGrid = new String[]{
"  +-+",
"  | |",
"+-+-+",
"| | |",
"+-+-+"
};

assertEquals(5, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testThatRectangleOfHeightOneIsCounted() {
String[] inputGrid = new String[]{
"+--+",
"+--+"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testThatRectangleOfWidthOneIsCounted() {
String[] inputGrid = new String[]{
"++",
"||",
"++"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testThatOneByOneSquareIsCounted() {
String[] inputGrid = new String[]{
"++",
"++"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testThatIncompleteRectanglesAreNotCounted() {
String[] inputGrid = new String[]{
"  +-+",
"    |",
"+-+-+",
"| | -",
"+-+-+"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testThatRectanglesOfDifferentSizesAreAllCounted() {
String[] inputGrid = new String[]{
"+------+----+",
"|      |    |",
"+---+--+    |",
"|   |       |",
"+---+-------+"
};

assertEquals(3, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testThatIntersectionsWithoutCornerCharacterDoNotCountAsRectangleCorners() {
String[] inputGrid = new String[]{
"+------+----+",
"|      |    |",
"+------+    |",
"|   |       |",
"+---+-------+"
};

assertEquals(2, rectangleCounter.countRectangles(inputGrid));
}

@Ignore("Remove to run test")
@Test
public void testLargeInputWithManyRectangles() {
String[] inputGrid = new String[]{
"+---+--+----+",
"|   +--+----+",
"+---+--+    |",
"|   +--+----+",
"+---+--+--+-+",
"+---+--+--+-+",
"+------+  | |",
"          +-+"
};

assertEquals(60, rectangleCounter.countRectangles(inputGrid));
}

}``````

### src/main/java/RectangleCounter.java

``````import java.util.stream.IntStream;

public class RectangleCounter
{

public RectangleCounter(){}

public int countRectangles(String[] inputGrid)
{
if ((inputGrid.length == 0) || ("".equals(inputGrid[0].trim()))){
return 0;
}

return IntStream.range(0, inputGrid.length).map(i -> this.searchVertexOnY(inputGrid, i)).sum();
}

private int searchVertexOnY(String[] inputGrid, final int i)
{
return IntStream.range(0, inputGrid[i].length()).map(j -> this.searchVertexOnX(inputGrid, j, i)).sum();
}

private int searchVertexOnX(String[] inputGrid, final int j, final int i)
{
int count = 0;
if (inputGrid[i].charAt(j) == '+'){
// Search vertex on X
int jMax = IntStream.range(j+1, inputGrid[i].length()).filter(x -> ((inputGrid[i].charAt(x) != '+') && (inputGrid[i].charAt(x) != '-')))
.findFirst()
.orElse(inputGrid[i].length());
count += IntStream.range(j+1, jMax).map(x -> this.searchVertexOnX(inputGrid, j, i, x)).sum();
}
return count;
}

private int searchVertexOnX(String[] inputGrid, final int j, final int i, final int x)
{
int count = 0;
if (inputGrid[i].charAt(x) == '+'){
// Search vertex on Y
int iMax = IntStream.range(i+1, inputGrid.length).filter(y -> (inputGrid[y].charAt(j) != '+') && (inputGrid[y].charAt(j) != '|'))
.findFirst()
.orElse(inputGrid.length);
count += IntStream.range(i+1, iMax).filter(y -> this.searchVertexOnY(inputGrid, j, i, x, y)).count();
}
return count;
}

private boolean searchVertexOnY(String[] inputGrid, final int j, final int i, final int x, final int y)
{
boolean foundVertexOnY = false;
if (inputGrid[y].charAt(j) == '+'){
// Search last vertex (X, Y)
if (inputGrid[y].charAt(x) == '+'){
// Validate rectangle
if (this.validateRectangle(inputGrid, j, i, x, y)){
foundVertexOnY = true;
}
}
}
return foundVertexOnY;
}

private boolean validateRectangle(String[] inputGrid, final int j, final int i, final int x, final int y)
{
boolean validRectangle = IntStream.range(i+1, y).allMatch(y0 -> ((inputGrid[y0].charAt(x) == '|') || (inputGrid[y0].charAt(x) == '+')));
if (validRectangle){
validRectangle = IntStream.range(j+1, x).allMatch(x0 -> (inputGrid[y].charAt(x0) == '-') || (inputGrid[y].charAt(x0) == '+'));
}
return validRectangle;
}

}``````

### src/test/java/RectangleCounterTest.java

``````import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class RectangleCounterTest {

private RectangleCounter rectangleCounter;

@Before
public void setUp() {
rectangleCounter = new RectangleCounter();
}

@Test
public void testInputWithNoRowsContainsNoRectangles() {
String[] inputGrid = new String[]{};

assertEquals(0, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testInputWithNoColumnsContainsNoRectangles() {
String[] inputGrid = new String[]{""};

assertEquals(0, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testNonTrivialInputWithNoRectangles() {
String[] inputGrid = new String[]{" "};

assertEquals(0, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testInputWithOneRectangle() {
String[] inputGrid = new String[]{
"+-+",
"| |",
"+-+"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testInputWithTwoRectanglesWithoutSharedEdges() {
String[] inputGrid = new String[]{
"  +-+",
"  | |",
"+-+-+",
"| |  ",
"+-+  "
};

assertEquals(2, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testInputWithFiveRectanglesWithSharedEdges() {
String[] inputGrid = new String[]{
"  +-+",
"  | |",
"+-+-+",
"| | |",
"+-+-+"
};

assertEquals(5, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testThatRectangleOfHeightOneIsCounted() {
String[] inputGrid = new String[]{
"+--+",
"+--+"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testThatRectangleOfWidthOneIsCounted() {
String[] inputGrid = new String[]{
"++",
"||",
"++"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testThatOneByOneSquareIsCounted() {
String[] inputGrid = new String[]{
"++",
"++"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testThatIncompleteRectanglesAreNotCounted() {
String[] inputGrid = new String[]{
"  +-+",
"    |",
"+-+-+",
"| | -",
"+-+-+"
};

assertEquals(1, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testThatRectanglesOfDifferentSizesAreAllCounted() {
String[] inputGrid = new String[]{
"+------+----+",
"|      |    |",
"+---+--+    |",
"|   |       |",
"+---+-------+"
};

assertEquals(3, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testThatIntersectionsWithoutCornerCharacterDoNotCountAsRectangleCorners() {
String[] inputGrid = new String[]{
"+------+----+",
"|      |    |",
"+------+    |",
"|   |       |",
"+---+-------+"
};

assertEquals(2, rectangleCounter.countRectangles(inputGrid));
}

//@Ignore("Remove to run test")
@Test
public void testLargeInputWithManyRectangles() {
String[] inputGrid = new String[]{
"+---+--+----+",
"|   +--+----+",
"+---+--+    |",
"|   +--+----+",
"+---+--+--+-+",
"+---+--+--+-+",
"+------+  | |",
"          +-+"
};

assertEquals(60, rectangleCounter.countRectangles(inputGrid));
}

}``````