Skip to content

Commit c679857

Browse files
committed
Added hard/intersecting_lines
1 parent efb6457 commit c679857

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

hard/intersecting_lines.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* Using the JavaScript language, have the function intersectingLines(strArr)
3+
* take strArr which will be an array of 4 coordinates in the form: (x,y). Your
4+
* program should take these points where the first 2 form a line and the last 2
5+
* form a line, and determine whether the lines intersect, and if they do, at
6+
* what point. For example: if strArr is ["(3,0)","(1,4)","(0,-3)","(2,3)"],
7+
* then the line created by (3,0) and (1,4) and the line created by (0,-3) (2,3)
8+
* intersect at (9/5,12/5). Your output should therefore be the 2 points in
9+
* fraction form in the following format: (9/5,12/5). If there is no denominator
10+
* for the resulting points, then the output should just be the integers like
11+
* so: (12,3). If any of the resulting points is negative, add the negative sign
12+
* to the numerator like so: (-491/63,-491/67). If there is no intersection,
13+
* your output should return the string "no intersection". The input points and
14+
* the resulting points can be positive or negative integers.
15+
*
16+
* https://www.coderbyte.com/results/bhanson:Intersecting%20Lines:JavaScript
17+
*
18+
* @param {array} strArr
19+
* @return {string}
20+
*/
21+
function intersectingLines(strArr) {
22+
// https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
23+
const [x1, y1, x2, y2, x3, y3, x4, y4] = strArr
24+
.join('')
25+
.match(/-?\d+/g)
26+
.map(Number);
27+
28+
// https://wikimedia.org/api/rest_v1/media/math/render/svg/c51a9b486a6ef5a7a08b92d75e71a07888034a9a
29+
const pxNumerator =
30+
(x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);
31+
const pxDenominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
32+
33+
const pyNumerator =
34+
(x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);
35+
const pyDenominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
36+
37+
// The problem is solved at this point, but we need to format the answer to spec
38+
39+
if (pxDenominator === 0 || pyDenominator === 0) {
40+
return 'no intersection';
41+
}
42+
43+
const pxString = formatFractionToString(pxNumerator, pxDenominator);
44+
const pyString = formatFractionToString(pyNumerator, pyDenominator);
45+
46+
return `(${pxString},${pyString})`;
47+
}
48+
49+
function greatestCommonFactor(num0, num1) {
50+
num0 = Math.abs(num0);
51+
num1 = Math.abs(num1);
52+
53+
if (num0 === 0) return num1;
54+
if (num1 === 0) return num0;
55+
56+
const max = Math.min(num0, num1);
57+
let gcf = 1;
58+
for (let i = 1; i <= max; i++) {
59+
if (num0 % i === 0 && num1 % i === 0) {
60+
gcf = i;
61+
}
62+
}
63+
return gcf;
64+
}
65+
66+
function formatFractionToString(numerator, denominator) {
67+
// Reduce fraction
68+
const gcf = greatestCommonFactor(numerator, denominator);
69+
numerator /= gcf;
70+
denominator /= gcf;
71+
72+
// Combine signs and remove from elements to add at end
73+
sign = Math.sign(numerator) * Math.sign(denominator) === 1 ? '' : '-';
74+
numerator = Math.abs(numerator);
75+
denominator = Math.abs(denominator);
76+
77+
let str;
78+
if (numerator === 0) {
79+
str = '0';
80+
} else if (numerator === denominator || denominator === 1) {
81+
str = `${sign}${numerator}`;
82+
} else {
83+
str = `${sign}${numerator}/${denominator}`;
84+
}
85+
86+
return str;
87+
}
88+
89+
module.exports = intersectingLines;

hard/intersecting_lines.test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const intersectingLines = require('./intersecting_lines');
2+
3+
describe('intersectingLines()', () => {
4+
test('passes Coderbyte.com tests', () => {
5+
expect(intersectingLines(['(3,0)', '(1,4)', '(0,-3)', '(2,3)'])).toBe(
6+
'(9/5,12/5)'
7+
);
8+
9+
expect(
10+
intersectingLines(['(0,15)', '(3,-12)', '(2,1)', '(13,7)'])
11+
).toBe('(166/105,27/35)');
12+
13+
expect(
14+
intersectingLines(['(1,2)', '(3,4)', '(-5,-6)', '(-7,-8)'])
15+
).toBe('no intersection');
16+
17+
expect(
18+
intersectingLines(['(10,11)', '(12,16)', '(6,7)', '(18,-4)'])
19+
).toBe('(318/41,221/41)');
20+
21+
expect(intersectingLines(['(0,0)', '(0,-1)', '(1,1)', '(0,1)'])).toBe(
22+
'(0,1)'
23+
);
24+
25+
expect(
26+
intersectingLines(['(9,-2)', '(-2,9)', '(3,4)', '(10,11)'])
27+
).toBe('(3,4)');
28+
29+
expect(
30+
intersectingLines(['(100,5)', '(6,2)', '(2,6)', '(5,100)'])
31+
).toBe('(170/91,170/91)');
32+
33+
expect(
34+
intersectingLines(['(1,-1)', '(1,1)', '(-5,-5)', '(-7,-7)'])
35+
).toBe('(1,1)');
36+
37+
expect(
38+
intersectingLines(['(6,12)', '(7,14)', '(-100,-3)', '(-3,-5)'])
39+
).toBe('(-491/196,-491/98)');
40+
41+
expect(
42+
intersectingLines(['(4,3)', '(2,1)', '(-7,-6)', '(-4,-1)'])
43+
).toBe('(-10,-11)');
44+
});
45+
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy