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
It's not elegant or pretty, but it seems to do the trick!
const NOT_POSSIBLE = 'NOT POSSIBLE';
function generate(A, B, C, D) {
var args = [A, B, C, D];
var idx = -1;
var out = NOT_POSSIBLE;
var firstN, secondN;
MAIN: {
args.sort(NUMERIC_ASCENDING);
// number has to start with 0, 1 or 2
if (args[0] > 2) break MAIN;
while (args[++idx] < 3) {}
// take the higest 2, 1, or 0
firstN = args[--idx];
args = pop(args, idx);
if (firstN === 2) {
// make sure that the first number doesn't exceed 23 and
// the second number 59
if (args[0] > 3 || args[0] > 1 && args[1] > 5)
break MAIN;
// advance to the first number < 3 or the length
idx = 0;
while (args[++idx] < 3){}
} else {
// much simpler if we have a 0 or 1, take the biggest n remaining
idx = args.length;
}
secondN = args[--idx];
args = pop(args, idx);
// if minutes number is too large, swap
if (args[0] > 5) {
out = '' + secondN + args[1] + ':' + firstN + args[0];
} else {
// if bottom number is low enough, swap for more minutes
out = '' + firstN + secondN + (args[1] < 6 ? ':' + args[1] + args[0] : ':' + args[0] + args[1]);
}
}
return out;
}
// numeric comparator for sort
function NUMERIC_ASCENDING(x, y) {
return x > y ? 1 : y > x ? -1 : 0;
}
// specialized "array pop" I wrote out longhand that's very optimized; might be cheating =D
function pop(arr, target) {
switch (arr.length) {
case 3:
switch (target) {
case 0: return [arr[1], arr[2]];
case 1: return [arr[0], arr[2]];
default: return [arr[0], arr[1]];
}
case 4:
switch (target) {
case 0: return [arr[1], arr[2], arr[3]];
case 1: return [arr[0], arr[2], arr[3]];
case 2: return [arr[0], arr[1], arr[3]];
default: return [arr[0], arr[1], arr[2]];
}
}
}
/* --------------- Start Speed Test --------------------- */
let startTime = Math.floor(Date.now());
let times = 10000;
let timesHolder = times;
while (times--) {
let A = randNum();
let B = randNum();
let C = randNum();
let D = randNum();
generate(A, B, C, D);
if (times == 0) {
let totalTime = Math.floor(Date.now()) - startTime;
let msg = timesHolder + ' Call Finished Within -> ' + totalTime + ' ms <-';
console.log(msg);
}
}
function randNum() {
return Math.floor(Math.random() * (9 - 0 + 1)) + 0;
}
/* --------------- END Speed Test --------------------- */