Skip to content

Commit 3bf0355

Browse files
committed
Added hard/line_ordering
1 parent 6803b7e commit 3bf0355

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

hard/line_ordering.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Using the JavaScript language, have the function lineOrdering(strArr) read
3+
* the strArr parameter being passed which will represent the relations among
4+
* people standing in a line. The structure of the input will be
5+
* ["A>B","B>C","A<D",etc..]. The letters stand for different people and the
6+
* greater than and less than signs stand for a person being in front of someone
7+
* or behind someone. A>B means A is in front of B and B<C means that B is
8+
* behind C in line. For example if strArr is: ["J>B","B<S","D>J"], these are
9+
* the following ways you can arrange the people in line: DSJB, SDJB and DJSB.
10+
* Your program will determine the number of ways people can be arranged in
11+
* line. So for this example your program should return the number 3. It also
12+
* may be the case that the relations produce an impossible line ordering,
13+
* resulting in zero as the answer.
14+
*
15+
* Only the symbols <, >, and the uppercase letters A...Z will be used. The
16+
* maximum number of relations strArr will contain is ten.
17+
*
18+
* https://www.coderbyte.com/results/bhanson:Line%20Ordering:JavaScript
19+
*
20+
* @param {array} strArr
21+
* @return {number}
22+
*/
23+
function lineOrdering(strArr) {
24+
// Unique people
25+
const people = Array.from(new Set(strArr.join(',').match(/[A-Z]+/g)));
26+
27+
// Brute-force all permutations
28+
const peoplePermutations = permute(people);
29+
const validPermutations = [];
30+
31+
peoplePermutations.forEach(permutation => {
32+
const permutationValid = relationsPossible(permutation, strArr);
33+
if (permutationValid) {
34+
validPermutations.push(permutation);
35+
}
36+
});
37+
38+
return validPermutations.length;
39+
}
40+
41+
function relationsPossible(people, relations) {
42+
for (let i = 0; i < relations.length; i++) {
43+
let [personA, relationship, personB] = relations[i].split('');
44+
45+
// Switch everything to A > B
46+
if (relationship === '<') {
47+
[personB, personA] = [personA, personB];
48+
}
49+
50+
const indexPersonA = people.indexOf(personA);
51+
const indexPersonB = people.indexOf(personB);
52+
53+
if (indexPersonA <= indexPersonB) {
54+
return false;
55+
}
56+
}
57+
return true;
58+
}
59+
60+
// https://en.wikipedia.org/wiki/Heap's_algorithm
61+
// Iterative
62+
function permute(arr) {
63+
let count = Array(arr.length).fill(0);
64+
65+
const results = [arr.slice()];
66+
67+
let i = 0;
68+
while (i < arr.length) {
69+
if (count[i] < i) {
70+
if (i % 2 === 0) {
71+
const temp = arr[0];
72+
arr[0] = arr[i];
73+
arr[i] = temp;
74+
} else {
75+
const temp = arr[count[i]];
76+
arr[count[i]] = arr[i];
77+
arr[i] = temp;
78+
}
79+
results.push(arr.slice());
80+
count[i]++;
81+
i = 0;
82+
} else {
83+
count[i] = 0;
84+
i++;
85+
}
86+
}
87+
return results;
88+
}
89+
90+
module.exports = lineOrdering;

hard/line_ordering.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const lineOrdering = require('./line_ordering');
2+
3+
describe('lineOrdering()', () => {
4+
test('passes Coderbyte.com tests', () => {
5+
expect(lineOrdering(['A>B', 'A<C', 'C<Z'])).toBe(1);
6+
7+
expect(lineOrdering(['A>B', 'B<R', 'R<G'])).toBe(3);
8+
9+
expect(lineOrdering(['J>B', 'B<S', 'D>J'])).toBe(3);
10+
11+
expect(lineOrdering(['A>B', 'B<C'])).toBe(2);
12+
13+
expect(lineOrdering(['A>B', 'B>C', 'C>D'])).toBe(1);
14+
15+
expect(lineOrdering(['A>B', 'B>C', 'C>D', 'G>D'])).toBe(4);
16+
17+
expect(lineOrdering(['A>B', 'B>C', 'C>D', 'D>E', 'G>E'])).toBe(5);
18+
19+
expect(lineOrdering(['A>B', 'C>B', 'A<Q'])).toBe(3);
20+
21+
expect(lineOrdering(['A<B', 'B>A'])).toBe(1);
22+
23+
expect(lineOrdering(['A>C'])).toBe(1);
24+
});
25+
});

0 commit comments

Comments
 (0)