Divide and Conquer

Recursively breaking down a problem into two or more sub-problems of the same or related type, until these become simple enough to be solved directly.

Definition

Problem

sub-problem

sub-problem

Simple Problems

  • Number Classification

Complex Problems

Tower of Hanoi (河內塔)

  1. 將所有盤子從最左邊移到最右邊
  2. 大盤子不可疊在小盤子上

Tower of Hanoi

function hanoi(n, a, b, c) {
    if(n === 1) {
        return [{
          from : a,
          to : c,
        }];
    }

    return hanoi(n - 1, a, c, b).concat(
           hanoi(1, a, b, c), 
           hanoi(n - 1, b, a, c)
    );
}
    
hanoi(3, 'A', 'B', 'C').forEach(function(move) {
    print('盤從 ' + move.from + ' 移至 ' + move.to);
});
T(n) = 2^n - 1
T(n)=2n1T(n) = 2^n - 1

Tower of Hanoi

傳說在古老的印度,有一座神廟,據說它是宇宙的中心。在廟宇中放置了一塊上面插有三根長木釘的木板,在其中的一根木釘上,從上至下被放置了64片直徑由小至大的圓環形金屬片。按照規則移動,當這些金屬片全數被移到另一根木釘上時,世界就將毀滅。

 

需要次數:18,446,744,073,709,551,615

假設每秒搬一次不眠不休:約 584,942,417,355

To iterate is human, to recurse, divine

Sorting


Array.sort();
  • Chrome(V8): Quick sort + Insertion sort(len <= 10)
  • Firefox/Mozilla: Merge sort
  • ​Safari: Selection sort
  • IE: Selection sort

Permutation

Q: 假設有10題題目,每題皆有2個答案,請產出所有答案組合


[
  [0, 1], // Q1
  [2, 3], // Q2
  [4, 5],
  [6, 7],
  [8, 9],
  [10, 11],
  [12, 13],
  [14, 15],
  [16, 17],
  [18, 19] // Q10
]

[
  [0, 2, 4, 6, 8, 10, 12, 14, 16, 18], // A1
  [0, 2, 4, 6, 8, 10, 12, 14, 16, 19], // A2
  ...
  ...
  [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] // A1024
]

原始答案

答案組合

Permutation

Q: 假設有10題題目,每題皆有2個答案,請產出所有答案組合


function version1(args) {
  return (
    args.reduce((acc, curr) => (
      _.flatten(acc.map(answerGroup => (
        curr.map(answer => answerGroup.concat([answer])) // group length: acc * curr
      )))
    ), [[]])
  );
}

[[0, 1], [2, 3] ... , [18, 19]]

[[]] 

[[0], [1]]

[[0, 2], [0, 3], [1, 2], [1, 3]]

...

V1

Q: 假設有10題題目,每題皆有2個答案,請產出所有答案組合


function version2(args) {
   const result = [];
   const max = args.length - 1;
  
   function permuteHelper(arr, questionIdx) {
     if (args[questionIdx]) {
       args[questionIdx].map((arg) => {
         const tempArray = arr.slice(0); // clone arr

         tempArray.push(arg);
  
         if (questionIdx === max) {
           return result.push(tempArray);
         }
  
         return permuteHelper(tempArray, questionIdx + 1);
       });
     }
   }
  
   permuteHelper([], 0);
  
   return result;
}

[[0, 1], [2, 3] ... , [18, 19]]

V2

Q: 假設有10題題目,每題皆有2個答案,請產出所有答案組合

[[0, 1], [2, 3] ... , [18, 19]]

0

1

2

3

4

5

4

5

2

3

.

.

.

.

.

.

permuteHelper([], 0)

permuteHelper([0], 1)

permuteHelper([1], 1)

permuteHelper([0, 2], 2)

permuteHelper([0, 3], 2)

permuteHelper([1, 2], 2)

permuteHelper([1, 3], 2)

Chrome (1024個解)

Firefox (1024個)

Safari (1024個)

Divide and Conquer

By Travor Lee

Divide and Conquer

  • 186