Home > Enterprise >  Valid Times on a Digital Clock
Valid Times on a Digital Clock

Time:10-08

This question has been bugging me ever since I got it in a Interview and couldn't figure it out and I've not been able to find a solution anywhere, especially in Javascript:

Given 4 Digits, count how many valid Times can be displayed ib a Digital Clock (in 24hr format) using those digits. Earliest Time is 00:00 and latest is 23:59.

Write a Function:

function solution(A,B,C,D);

That, given 4 intergers A,B,C,D, returns the number of valid times that can be displayed on a digital clock

CodePudding user response:

Start by writing a validating function that tells you whether 4 digits make up a legit time:

function validate(A,B,C,D){
    let hours =  (""   A   B),
        mins =  (""   C   D);
    return hours <= 23 
        && hours >= 0 
        && mins >= 0
        && mins < 60
}

Then given 4 digits, before you can use the above, you need to generate random orders of those 4 digits. So take any permutation function:

const permutations = arr => {
  if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr;
  return arr.reduce(
    (acc, item, i) =>
      acc.concat(
        permutations([...arr.slice(0, i), ...arr.slice(i   1)]).map(val => [
          item,
          ...val,
        ])
      ),
    []
  );
};

This will take an array of numbers like permutations([1,2,4,5]). The issue is this function will generate 24 element array even if you give it [1,1,1,1]. So you need to filter the unique ones:

const unique = arr => {
    return arr.reduce((ac,d) => {
        if(!ac.some(perm => d.join("") === perm.join(""))){
            ac.push(d);
        }
        return ac;
    },[])
}

Now you can write your solution combining above 3 functions:

function solution (A,B,C,D){
    return unique(permutations([A,B,C,D])).reduce((ac,d) => ac  = validate(...d),0)
}

For example:

solution(1,1,6,1) //2

I am absolutely sure it can written tidier and more concise, I might have forgotten something as well, so take everything with a pinch of salt

CodePudding user response:

You're pretty new here. A reminder if you haven't done it, please take the tour, visit the help center and read up on asking good questions. After doing some research and searching for related topics on SO, try it yourself. If you're stuck, post a minimal, reproducible example of your attempt and note exactly where you're stuck.

I wouldn't answer without your demonstrated effort if there was not already a working answer posted.


Because there are only 24 permutations of the four digits, it might be easiest just to include them directly in the code. One solution would use a simple predicate (isValidTime) on four digits to see if they constitute a valid time, and then use a string representation of each possible permutation, convert them to four-digit strings, use the [... new Set (xs)] trick to find an array of the unique ones, collect the ones that match our validity predicate, and finally return the length of that array. It might look like this:

const isValidTime = (A, B, C, D, h = 10 * A   B, m = 10 * C   D) => 
  0 <= h && h <= 23 && 0 <= m && m <= 59 // ? `${A}${B}${C}${D}` : false

const countValidTimes = (A, B, C, D, x = {A, B, C, D}) => 
  [... new Set ([
    "ABCD", "ABDC", "ACBD", "ACDB", "ADBC", "ADCB", "BACD", "BADC", 
    "BCAD", "BCDA", "BDAC", "BDCA", "CABD", "CADB", "CBAD", "CBDA", 
    "CDAB", "CDBA", "DABC", "DACB", "DBAC", "DBCA", "DCAB", "DCBA"
  ] .map (([...cs]) => cs .map (c => x [c]) .join (''))
  )] .filter (s => isValidTime (... s .split ('') .map (d => Number(d)))) .length

console .log (countValidTimes (8, 6, 1, 5))  
  //=> 2  (18:56, 16:58)
console .log (countValidTimes (1, 2, 3, 4))  
  //=> 10  (12:34, 12:43, 13:24, 13:42, 14:23, 14:32, 21:34, 21:43, 23:14, 23:41)
console .log (countValidTimes (1, 4, 1, 4))  
  //=> 3  (14:14, 14:41, 11:44)
console .log (countValidTimes (1, 1, 1, 1))
  //=> 1 (11:11)
console .log (countValidTimes (8, 6, 7, 5))  
  //=> 0

  • Related