Skip to content

Commit 0f92b3c

Browse files
committed
Added medium/overlaping_rectangles
1 parent 06d08a4 commit 0f92b3c

File tree

2 files changed

+203
-0
lines changed

2 files changed

+203
-0
lines changed

medium/overlaping_rectangles.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/**
2+
* Using the JavaScript language, have the function
3+
* overlappingRectangles(strArr) read the strArr parameter being passed which
4+
* will represent two rectangles on a Cartesian coordinate plane and will
5+
* contain 8 coordinates with the first 4 making up rectangle 1 and the last 4
6+
* making up rectange 2. It will be in the following format:
7+
* ["(0,0),(2,2),(2,0),(0,2),(1,0),(1,2),(6,0),(6,2)"] Your program should
8+
* determine the area of the space where the two rectangles overlap, and then
9+
* output the number of times this overlapping region can fit into the first
10+
* rectangle. For the above example, the overlapping region makes up a rectangle
11+
* of area 2, and the first rectangle (the first 4 coordinates) makes up a
12+
* rectangle of area 4, so your program should output 2. The coordinates will
13+
* all be integers. If there's no overlap between the two rectangles return 0.
14+
*
15+
* https://www.coderbyte.com/results/bhanson:Overlapping%20Rectangles:JavaScript
16+
*
17+
* @param {array} strArr Array with one string element
18+
* @return {number} Number of times area of overlap can fit in first rectangle
19+
*/
20+
function overlapingRectangles(strArr) {
21+
// Convert coords from this format:
22+
// ['(0,0),(2,2),(2,0),(0,2),(1,0),(1,2),(6,0),(6,2)']
23+
// To this format:
24+
// [[0,0],[2,2],[2,0],[0,2],[1,0],[1,2],[6,0],[6,2]]
25+
const coords = strArr[0]
26+
.match(/(-?[0-9]+,-?[0-9]+)/g)
27+
.map(pair => pair.split(',').map(num => Number(num)));
28+
29+
const rect0 = Rectangle.fromCoords(coords.splice(0, 4));
30+
const rect1 = Rectangle.fromCoords(coords);
31+
32+
const overlap = Rectangle.areaOverlapping(rect0, rect1);
33+
34+
// Per spec, if no overlap return 0 (otherwise it would return `Infinity`)
35+
if (overlap === 0) {
36+
return 0;
37+
}
38+
39+
const numOverlapFitsInRect0 = Math.floor(rect0.area() / overlap);
40+
41+
return numOverlapFitsInRect0;
42+
}
43+
44+
function Rectangle(x, y, width, height) {
45+
this.x = x;
46+
this.y = y;
47+
this.width = width;
48+
this.height = height;
49+
}
50+
51+
// Iterates through each point, left-to-right, top-to-bottom
52+
Rectangle.prototype[Symbol.iterator] = function*() {
53+
for (let row = this.y; row < this.y + this.height; row++) {
54+
for (let col = this.x; col < this.x + this.width; col++) {
55+
yield [col, row];
56+
}
57+
}
58+
};
59+
60+
// Returns a new Rectangle object from an array of coordinates
61+
Rectangle.fromCoords = function(coordsArray) {
62+
if (coordsArray.length !== 4) {
63+
return null;
64+
}
65+
66+
const xCoords = coordsArray.map(coords => coords[0]).sort();
67+
const yCoords = coordsArray.map(coords => coords[1]).sort();
68+
69+
// For a valid rectangle, there should be pairs of x and y coords
70+
if (
71+
xCoords[0] !== xCoords[1] ||
72+
xCoords[2] !== xCoords[3] ||
73+
yCoords[0] !== yCoords[1] ||
74+
yCoords[2] !== yCoords[3]
75+
) {
76+
// Coords are not rectangle
77+
return null;
78+
}
79+
80+
const [x1, , x2] = xCoords;
81+
const [y1, , y2] = yCoords;
82+
83+
const width = Math.abs(x1 - x2);
84+
const height = Math.abs(y1 - y2);
85+
const x = Math.min(x1, x2);
86+
const y = Math.min(y1, y2);
87+
88+
return new Rectangle(x, y, width, height);
89+
};
90+
91+
Rectangle.areaOverlapping = function(rectangle0, rectangle1) {
92+
let overlap = 0;
93+
for (const coords of rectangle1) {
94+
if (rectangle0.containsCoords(coords)) {
95+
overlap++;
96+
}
97+
}
98+
return overlap;
99+
};
100+
101+
Rectangle.prototype.containsCoords = function(coords) {
102+
let [x, y] = coords;
103+
if (
104+
x >= this.x &&
105+
x < this.x + this.width &&
106+
y >= this.y &&
107+
y < this.y + this.height
108+
) {
109+
return true;
110+
}
111+
return false;
112+
};
113+
114+
Rectangle.prototype.area = function() {
115+
return this.width * this.height;
116+
};
117+
118+
module.exports = overlapingRectangles;

medium/overlaping_rectangles.test.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
const overlapingRectangles = require('./overlaping_rectangles');
2+
3+
describe('overlapingRectangles()', () => {
4+
test('correctly number of times overlapped area can fit in first rectangle', () => {
5+
expect(
6+
overlapingRectangles([
7+
'(0,0),(2,2),(2,0),(0,2),(1,0),(1,2),(6,0),(6,2)'
8+
])
9+
).toBe(2);
10+
11+
expect(
12+
overlapingRectangles([
13+
'(0,0),(0,-2),(3,0),(3,-2),(2,-1),(3,-1),(2,3),(3,3)'
14+
])
15+
).toBe(6);
16+
17+
expect(
18+
overlapingRectangles([
19+
'(0,0),(5,0),(0,2),(5,2),(2,1),(5,1),(2,-1),(5,-1)'
20+
])
21+
).toBe(3);
22+
});
23+
24+
test('passes Coderbyte.com tests', () => {
25+
expect(
26+
overlapingRectangles([
27+
'(0,0),(0,-2),(3,0),(3,-2),(2,-1),(3,-1),(2,3),(3,3)'
28+
])
29+
).toBe(6);
30+
31+
expect(
32+
overlapingRectangles([
33+
'(0,0),(2,0),(0,4),(2,4),(0,1),(2,1),(0,4),(2,4)'
34+
])
35+
).toBe(1);
36+
37+
expect(
38+
overlapingRectangles([
39+
'(0,0),(0,-2),(3,0),(3,-2),(2,-2),(3,-2),(2,20),(3,20)'
40+
])
41+
).toBe(3);
42+
43+
expect(
44+
overlapingRectangles([
45+
'(0,0),(1,0),(0,1),(1,1),(0,0),(2,0),(0,-1),(2,-1)'
46+
])
47+
).toBe(0);
48+
49+
expect(
50+
overlapingRectangles([
51+
'(0,0),(5,0),(0,2),(5,2),(3,1),(5,1),(3,-1),(5,-1)'
52+
])
53+
).toBe(5);
54+
55+
expect(
56+
overlapingRectangles([
57+
'(0,0),(5,0),(0,2),(5,2),(2,1),(5,1),(2,-1),(5,-1)'
58+
])
59+
).toBe(3);
60+
61+
expect(
62+
overlapingRectangles([
63+
'(1,0),(1,1),(4,0),(4,1),(3,0),(4,0),(3,1),(4,1)'
64+
])
65+
).toBe(3);
66+
67+
expect(
68+
overlapingRectangles([
69+
'(1,0),(1,1),(4,0),(4,1),(2,0),(4,0),(2,1),(4,1)'
70+
])
71+
).toBe(1);
72+
73+
expect(
74+
overlapingRectangles([
75+
'(1,0),(1,1),(4,0),(4,1),(5,0),(27,0),(5,-25),(27,-25)'
76+
])
77+
).toBe(0);
78+
79+
expect(
80+
overlapingRectangles([
81+
'(5,0),(-2,0),(5,-1),(-2,-1),(3,-1),(5,-1),(3,56),(5,56)'
82+
])
83+
).toBe(3);
84+
});
85+
});

0 commit comments

Comments
 (0)