Skip to content

Commit 307159c

Browse files
committed
Added hard/optimal_assignments
1 parent 1249a94 commit 307159c

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

hard/optimal_assignments.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Using the JavaScript language, have the function optimalAssignments(strArr)
3+
* read strArr which will represent an NxN matrix and it will be in the
4+
* following format: ["(n,n,n...)","(...)",...] where the n's represent
5+
* integers. This matrix represents a machine at row i performing task at column
6+
* j. The cost for this is matrix[i][j]. Your program should determine what
7+
* machine should perform what task so as to minimize the whole cost and it
8+
* should return the pairings of machines to tasks in the following format:
9+
* (i-j)(...)... Only one machine can perform one task. For example: if strArr
10+
* is ["(5,4,2)","(12,4,3)","(3,4,13)"] then your program should return
11+
* (1-3)(2-2)(3-1) because assigning the machines to these tasks gives the least
12+
* cost. The matrix will range from 2x2 to 6x6, there will be no negative costs
13+
* in the matrix, and there will always be a unique answer.
14+
*
15+
* https://www.coderbyte.com/results/bhanson:Optimal%20Assignments:JavaScript
16+
*
17+
* @param {array} strArr
18+
* @return {string}
19+
*/
20+
function optimalAssignments(strArr) {
21+
// Parse input to 2d array
22+
const matrix = strArr.map(row => row.match(/\d+/g).map(Number));
23+
24+
// Array index = machine (row)
25+
// Array value = task (col)
26+
const tasks = [];
27+
for (let i = 0; i < strArr.length; i++) {
28+
tasks.push(i);
29+
}
30+
31+
// Brute force check all possibilities
32+
const permutations = permute(tasks);
33+
34+
let minCost = Number.MAX_SAFE_INTEGER;
35+
let minAssignment = [];
36+
permutations.forEach(permutation => {
37+
const cost = getTotalCost(matrix, permutation);
38+
39+
if (cost < minCost) {
40+
minCost = cost;
41+
minAssignment = permutation;
42+
}
43+
});
44+
45+
// Format output to spec
46+
const result = minAssignment
47+
.map((value, index) => `(${index + 1}-${value + 1})`)
48+
.join('');
49+
50+
return result;
51+
}
52+
53+
function getTotalCost(matrix, assignment) {
54+
let cost = 0;
55+
for (let i = 0; i < assignment.length; i++) {
56+
cost += matrix[i][assignment[i]];
57+
}
58+
return cost;
59+
}
60+
61+
// https://en.wikipedia.org/wiki/Heap's_algorithm
62+
// Iterative
63+
function permute(arr) {
64+
let count = Array(arr.length).fill(0);
65+
66+
const results = [arr.slice()];
67+
68+
let i = 0;
69+
while (i < arr.length) {
70+
if (count[i] < i) {
71+
if (i % 2 === 0) {
72+
const temp = arr[0];
73+
arr[0] = arr[i];
74+
arr[i] = temp;
75+
} else {
76+
const temp = arr[count[i]];
77+
arr[count[i]] = arr[i];
78+
arr[i] = temp;
79+
}
80+
results.push(arr.slice());
81+
count[i]++;
82+
i = 0;
83+
} else {
84+
count[i] = 0;
85+
i++;
86+
}
87+
}
88+
return results;
89+
}
90+
91+
module.exports = optimalAssignments;

hard/optimal_assignments.test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const optimalAssignments = require('./optimal_assignments');
2+
3+
describe('optimalAssignments()', () => {
4+
test('passes Coderbyte.com tests', () => {
5+
expect(optimalAssignments(['(5,4,2)', '(12,4,3)', '(3,4,13)'])).toBe(
6+
'(1-3)(2-2)(3-1)'
7+
);
8+
9+
expect(optimalAssignments(['(1,2,1)', '(4,1,5)', '(5,2,1)'])).toBe(
10+
'(1-1)(2-2)(3-3)'
11+
);
12+
13+
expect(
14+
optimalAssignments([
15+
'(13,4,7,6)',
16+
'(1,11,5,4)',
17+
'(6,7,2,8)',
18+
'(1,3,5,9)'
19+
])
20+
).toBe('(1-2)(2-4)(3-3)(4-1)');
21+
22+
expect(optimalAssignments(['(1,1,4)', '(5,2,1)', '(1,5,2)'])).toBe(
23+
'(1-2)(2-3)(3-1)'
24+
);
25+
26+
expect(optimalAssignments(['(1,1,2)', '(2,1,5)', '(1,5,1)'])).toBe(
27+
'(1-1)(2-2)(3-3)'
28+
);
29+
30+
expect(optimalAssignments(['(1,4)', '(5,18)'])).toBe('(1-2)(2-1)');
31+
32+
expect(optimalAssignments(['(1,2)', '(1,1)'])).toBe('(1-1)(2-2)');
33+
34+
expect(
35+
optimalAssignments([
36+
'(13,2,7,1)',
37+
'(1,2,3,4)',
38+
'(6,7,2,3)',
39+
'(67,4,8,18)'
40+
])
41+
).toBe('(1-4)(2-1)(3-3)(4-2)');
42+
43+
expect(
44+
optimalAssignments([
45+
'(1,14,2,4)',
46+
'(5,1,4,15)',
47+
'(1,5,2,7)',
48+
'(1,4,7,17)'
49+
])
50+
).toBe('(1-4)(2-2)(3-3)(4-1)');
51+
52+
expect(
53+
optimalAssignments([
54+
'(90,75,75,80,82)',
55+
'(35,85,20,50,41)',
56+
'(40,2,24,1,67)',
57+
'(4,70,2,11,23)',
58+
'(23,25,56,44,21)'
59+
])
60+
).toBe('(1-2)(2-3)(3-4)(4-1)(5-5)');
61+
});
62+
});

0 commit comments

Comments
 (0)