Find maximum possible time HH:MM by permuting four given digits

前端 未结 23 2092
执念已碎
执念已碎 2020-11-30 02:44

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

23条回答
  •  情歌与酒
    2020-11-30 02:54

    Well, starting from this suggestion about permutations in JavaScript, where, given an array of values get all possible unique permutations, I got this solution:

    • Assuming you have all possible combinations with 4 digits,
    • and assuming that a right hours value is in the range 00-23
    • and assuming that a right minutes value is in the range 00-59

    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));

提交回复
热议问题