Problem Description
Write a program to find the maximum number of rectangles that can be formed both horizontal and vertical with the help of a given n number of coordinate(x,y) points. [x,y points will always be positive].
The method getRectangleCount takes 1 input parameter which is an int array called
coOrdinates
.The method
getRectangleCount
takes the coordinates as a 2D integer array and returns the maximum number of rectangles as an integer.public int getRectangleCount(int[][] coOrdinates)
There is no need to count the rectangles that can be created from the overlapping rectangles.
Example
Input :
int coordinates[][] = { {1,1}, {7,1}, {1,4}, {1,5}, {7,4}, {7,5} }
Output : Returns 3
Explanation:
Three rectangles can be formed.
First -
(1,4)----(7,4) | | | | (1,1)----(7,1)
Second -
(1,5)----(7,5) | | | | (1,1)----(7,1)
Third -
(1,5)----(7,5) | | | | (1,4)----(7,4)
My Concerns
- Is it readable? Is it maintainable? I intentionally didn't comment in the code because I want to see if the code is self-explanatory or not.
for
insidefor
insideif
inside.... you get the picture... Is it nasty?- Can it be optimized, as it is from a programming challenge, time is a factor.
My Solution
You can browse the GitHub Project for more info.
public int getRectangleCount(int [][]coOrdinates) {
// exception handling part coded here... forget about it
final int MIN_POINTS_TO_CREATE_RECTANGLE = 4;
// can't make a rectangle with less than 4 points
if(coOrdinates.length < MIN_POINTS_TO_CREATE_RECTANGLE)
return 0;
final Point []points = new Point[coOrdinates.length];
for(int i = 0; i < coOrdinates.length; i++)
points[i] = new Point(coOrdinates[i][0], coOrdinates[i][1]);
Arrays.sort(points); // points are sorted like (1,1) (1,3) (3,1) (3,3)....
int rectangleCount = 0;
for(int i = 0; i < points.length; i++) {
Point leftDown = points[i];
for(int j = i+1; j < points.length; j++) {
Point leftUp = points[j];
if(leftDown.getX() == leftUp.getX()) {
for(int k = j+1; k < points.length; k++) {
Point rightDown = points[k];
Point probableRightUp = new Point(rightDown.getX(), leftUp.getY());
if((leftDown.getY() == rightDown.getY())
&&
probableRightUp.existsIn(points)) {
rectangleCount++;
}
}
}
}
}
return rectangleCount;
}
I also have a custom Point
class that implements Comparable<Point>
. Point
overrides compareTo()
method like following
@Override
public int compareTo(Point p) {
if(Integer.compare(this.getX(),p.getX()) == 0)
{
return Integer.compare(this.getY(), p.getY());
}
return Integer.compare(this.getX(),p.getX());
}
and method existsIn(Point []graph)
works like as you think. It returns true
if this
exists in the graph
else false
.
Yes I will create a Points
collection class later and will move existsIn(Point []graph)
. I will also change the signature to
public static boolean existsIn(Point []graph, Point toCheck) // Promise I will ;)
coOrdinates
should becoordinates
; see: en.wikipedia.org/wiki/Coordinate_system \$\endgroup\$int[][]
(space after brackets) overint [][]
(space before brackets); see: stackoverflow.com/a/129188/59087 and docs.oracle.com/javase/specs/jls/se7/html/jls-10.html \$\endgroup\$