简体   繁体   中英

Valid Times on a Digital Clock

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

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

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

maybe not the best solution but i think it's ez to understand. I used backtracking to resolve this problem. Faced this question in an interview too:D.

public static void main(String[] args) {
    //Driver
    int result = solution(6, 2, 4, 7);
    System.out.println(result);
}

public static int solution(int a, int b, int c, int d) {
    int[] arr = {-1, -1, -1, -1};
    Map<Integer, Integer> tracking = new HashMap<>();
    tracking.put(a, 0);
    tracking.put(b, 0);
    tracking.put(c, 0);
    tracking.put(d, 0);
    int[] track = {a, b, c, d};
    for (int i = 0; i < track.length; i++) {
        tracking.put(track[i], tracking.get(track[i]) + 1);
    }
    Set<String> set = new HashSet<>();
    possibleTime(a, b, c, d, arr, 0, tracking,set);
    return set.size();
}

public static int[] possibleTime(int a, int b, int c, int d, int[] arr, int index, Map<Integer, Integer> tracking,Set<String> set) {
    if (index == 4) {
        set.add(Arrays.toString(arr));
        return arr;
    }
    int[] pos = {a, b, c, d};
    for (int i = 0; i < pos.length; i++) {
        arr[index] = pos[i];
        tracking.put(pos[i], tracking.get(pos[i]) - 1);
        if (isValidTime(arr, tracking,set)) {
            index++;
            arr = possibleTime(a, b, c, d, arr, index, tracking,set);
            index--;

        }
        tracking.put(pos[i], tracking.get(pos[i]) + 1);
        arr[index] = -1;

    }
    return arr;
}

public static boolean isValidTime(int[] arr, Map<Integer, Integer> tracking,Set<String> set) {
    //check existed
    for (Integer in : tracking.keySet()) {
        if (tracking.get(in) < 0) {
            return false;
        }
    }
    if(set.contains(Arrays.toString(arr)))
    {
        return false;
    }
    //validate hh
    Map<Integer, Integer> hh = new HashMap<>();
    hh.put(1, 9);
    hh.put(2, 3);
    if (arr[0] != -1) {
        if (hh.containsKey(arr[0])) {
            if (arr[1] != -1 && arr[1] > hh.get(arr[0])) {
                return false;
            }
        } else {
            return false;
        }
    }
    //validate mmm
    if (arr[2] != -1 && arr[2] > 5) {
        return false;
    }
    if (arr[3] != -1 && arr[3] > 9) {
        return false;
    }

    return true;
}

def solution(A, B, C, D): times = 0 # check all possible hours for hour_tens in range(2): for hour_units in range(4): if (hour_tens == 2 and hour_units > 3): continue # check all possible minutes for min_tens in range(6): for min_units in range(10): if (str(hour_tens) + str(hour_units) + str(min_tens) + str(min_units)).count(str(A)) + (str(hour_tens) + str(hour_units) + str(min_tens) + str(min_units)).count(str(B)) + (str(hour_tens) + str(hour_units) + str(min_tens) + str(min_units)).count(str(C)) + (str(hour_tens) + str(hour_units) + str(min_tens) + str(min_units)).count(str(D)) == 4: times += 1 return times

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM