I recently took a coding test for a promotion at work. This was one of the tasks I really struggled with and was wondering what is the best way to do this. I used a load of
Well, starting from this suggestion about permutations in JavaScript, where, given an array of values get all possible unique permutations, I got this solution:
You can use this simple code to perform the action:
function maxTime(a, b, c, d) {
var ps = Array.from(uniquePermutations([a, b, c, d]));
while (maxHour = ps.pop()) {
var timing = maxHour.join('').replace(/([0-9]{2})([0-9]{2})/, '$1:$2');
if (/([0-1][0-9]|2[0-3])\:[0-5][0-9]/.test(timing)) {
return timing;
}
}
return false;
}
function swap(a, i, j) {
const t = a[i];
a[i] = a[j];
a[j] = t;
}
function reverseSuffix(a, start) {
if (start === 0) {
a.reverse();
} else {
let left = start;
let right = a.length - 1;
while (left < right)
swap(a, left++, right--);
}
}
function nextPermutation(a) {
// 1. find the largest index `i` such that a[i] < a[i + 1].
// 2. find the largest `j` (> i) such that a[i] < a[j].
// 3. swap a[i] with a[j].
// 4. reverse the suffix of `a` starting at index (i + 1).
//
// For a more intuitive description of this algorithm, see:
// https://www.nayuki.io/page/next-lexicographical-permutation-algorithm
const reversedIndices = [...Array(a.length).keys()].reverse();
// Step #1; (note: `.slice(1)` maybe not necessary in JS?)
const i = reversedIndices.slice(1).find(i => a[i] < a[i + 1]);
if (i === undefined) {
a.reverse();
return false;
}
// Steps #2-4
const j = reversedIndices.find(j => a[i] < a[j]);
swap(a, i, j);
reverseSuffix(a, i + 1);
return true;
}
function* uniquePermutations(a) {
const b = a.slice().sort();
do {
yield b.slice();
} while (nextPermutation(b));
}
function maxTime(a, b, c, d) {
var ps = Array.from(uniquePermutations([a, b, c, d]));
while (maxHour = ps.pop()) {
var timing = maxHour.join('').replace(/([0-9]{2})([0-9]{2})/, '$1:$2');
if (/([0-1][0-9]|2[0-3])\:[0-5][0-9]/.test(timing)) {
return timing;
}
}
return false;
}
console.log(maxTime(6, 5, 2, 0));
console.log(maxTime(3, 9, 5, 0));
console.log(maxTime(7, 6, 3, 8));