Advertisement
rg443

JavaScript algorithms snippets

Jan 30th, 2013
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // utils
  2.  
  3. Array.prototype.swap = function(a, b) {
  4.     if (a == b) {
  5.         return;
  6.     }
  7.     var tmp = this[a];
  8.     this[a] = this[b];
  9.     this[b] = tmp;
  10. };
  11.  
  12.  
  13. var produceRamdomArray = function(n, d) {
  14.     d = d || 18;
  15.     d = Math.pow(10, d);
  16.     var a = [];
  17.     while (n--) {
  18.         var b = Math.random();
  19.         a.push(Math.round(b*d));
  20.     }
  21.     return a;
  22. };
  23.  
  24.  
  25. var produceRamdomStrArray = function(n, d) {
  26.     var set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  27.     var a = [];
  28.     while (n--) {
  29.         var dd = d;
  30.         var s = '';
  31.         while (dd--) {
  32.             s += set.charAt(Math.floor(Math.random() * set.length));
  33.         }
  34.         a.push(s);
  35.     }
  36.     return a;
  37. };
  38.  
  39.  
  40. var checkSort = function(a) {
  41.     for (var i = 0; i != a.length-1; ++i) {
  42.         assert.ok(a[i] <= a[i+1], 'sort fail!');
  43.     }
  44. };
  45.  
  46.  
  47. // algorithms
  48.  
  49. var findSameElements = function(a, b) {
  50.     var ret = [];
  51.     var i = 0;
  52.     var j = 0;
  53.  
  54.     while (i < a.length && j < b.length) {
  55.         if (a[i] < b[j]) {
  56.             ++i;
  57.         } else if (a[i] > b[j]) {
  58.             ++j;
  59.         } else { // a[i] == b[j]
  60.             ret.push(a[i]);
  61.             ++i;
  62.             ++j;
  63.         }
  64.     }
  65.  
  66.     return ret;
  67. };
  68.  
  69.  
  70. var fibonacci = function(n) {
  71.     return (n == 0 || n == 1) ? n : fibonacci(n-1) + fibonacci(n-2);
  72. };
  73.  
  74.  
  75. var find2ndMax = function(a) {
  76.     var max = a[0];
  77.     var secMax = Number.NEGATIVE_INFINITY;
  78.  
  79.     for (var i = 0; i != a.length; ++i) {
  80.         if (a[i] > max) {
  81.             secMax = max;
  82.             max = a[i];
  83.         } else if (a[i] < max && a[i] > secMax) {
  84.             secMax = a[i];
  85.         }
  86.     }
  87.     return secMax;
  88. };
  89.  
  90.  
  91. var maxSubseqSum = function(a) {
  92.     var thisSum = 0;
  93.     var maxSum = 0;
  94.     for (var i = 0; i != a.length; ++i) {
  95.         thisSum += a[i];
  96.         if (thisSum > maxSum) {
  97.             maxSum = thisSum;
  98.         } else if (thisSum < 0) { // reset to 0
  99.             thisSum = 0;
  100.         }
  101.     }
  102.  
  103.     return maxSum;
  104. };
  105.  
  106.  
  107. var allRanges = function(a) {
  108.     var exchange = function(l, r) {
  109.         if (l == r) {
  110.             console.log(a);
  111.             return;
  112.         }
  113.         // exchange every elem to first position once
  114.         for (var i = l; i <= r; ++i) {
  115.             a.swap(l, i);
  116.             exchange(l+1, r);
  117.             a.swap(l, i);
  118.         }
  119.     };
  120.  
  121.     exchange(0, a.length-1);
  122. };
  123.  
  124.  
  125. var gcdAndLcm = function(a, b) {
  126.     var c = a * b;
  127.     while (b) {
  128.         var temp = b;
  129.         b = a % b;
  130.         a = temp;
  131.     }
  132.     console.log('GCD:', a);
  133.     console.log('LCM:', c/a);
  134. };
  135.  
  136.  
  137. var matrixRadio = function(n) {
  138.     for (var i = 0; i < 2*n-1; ++i) {
  139.         for (var j = 0; j < 2*n-1; ++j) {
  140.             var x = Math.abs(n-1-i);
  141.             var y = Math.abs(n-1-j);
  142.             process.stdout.write((n-(x>=y?x:y)).toString());
  143.         }
  144.         process.stdout.write('\n');
  145.     }
  146. };
  147.  
  148.  
  149. var matrixRound = function(n) {
  150.     // init arrays
  151.     a = [];
  152.     for (var i = 0; i != n; ++i) {
  153.         a[i] = [];
  154.     }
  155.  
  156.     var round = 0;
  157.     var m=1;
  158.  
  159.     while(m <= n*n) {
  160.         for (var i=round; i<=n-round-1; ++i) {
  161.             a[round][i] = m++;
  162.         }
  163.         for (var i=round+1; i<=n-round-1; ++i) {
  164.             a[i][n-round-1] = m++;
  165.         }
  166.         for (var i=n-round-2; i>=round; --i) {
  167.             a[n-round-1][i] = m++;
  168.         }
  169.         for (var i=n-round-2; i>=round+1; --i) {
  170.             a[i][round] = m++;
  171.         }
  172.         round++;
  173.     }
  174.  
  175.     return a;
  176. };
  177.  
  178.  
  179. var isPrimer = function(n) {
  180.     var ret = false;
  181.     if (n%2 != 0) {
  182.         ret = true;
  183.         for (var i = 3; i*i <= n; i += 2) {
  184.             if (n%i == 0) {
  185.                 ret = false;
  186.                 console.log('can be dived by', i);
  187.                 break;
  188.             }
  189.         }
  190.     }
  191. };
  192.  
  193.  
  194. var starDot = function(n) {
  195.     for (var i = 0; i != n; ++i) {
  196.         for (var j = 0; j != i; ++j) {
  197.             process.stdout.write('*');
  198.             for (var k = 0; k != i; ++k) {
  199.                 process.stdout.write('.');
  200.             }
  201.         }
  202.         process.stdout.write('\n');
  203.     }
  204. };
  205.  
  206.  
  207. var josephus = function(interval) {
  208.     var a = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
  209.     var index = -1;
  210.     for (var i = 0; i != a.length; ++i) {
  211.         for (var j = 0; j != interval;) { // count interval
  212.             index = (index+1)%a.length; // move forward
  213.             if (a[index] != 0) { // skip the outed
  214.                 ++j;
  215.             }
  216.         }
  217.         a[index] = 0; // kick out
  218.         console.log(a);
  219.     }
  220. };
  221.  
  222.  
  223. var findMiddle = function(a, b, c) {
  224.     var ret = c;
  225.     if ((a-b)*(a-c) < 0) {
  226.         ret = a;
  227.     } else if ((b-a)*(b-c) < 0) {
  228.         ret = b;
  229.     }
  230.     return ret;
  231. };
  232.  
  233.  
  234. var dec2bin = function(n) {
  235.     var ret = 0;
  236.     var deci = 1;
  237.     while (n) {
  238.         var t = n%2;
  239.         t *= deci;
  240.         deci *= 10;
  241.         ret += t;
  242.         n = Math.floor(n/2);
  243.     }
  244.     return ret;
  245. };
  246.  
  247.  
  248. var binarySearch = function(x) {
  249.     var ret;
  250.     var a = [0,1,2,3,4,5,6,7,8,9,10];
  251.     var l = 0;
  252.     var r = a.length-1;
  253.     while (l <= r) {
  254.         var t = Math.floor((l+r)/2);
  255.         if (x > a[t]) {
  256.             l = t + 1;
  257.         } else if (x < a[t]) {
  258.             r = t - 1;
  259.         } else {
  260.             ret = t;
  261.             break;
  262.         }
  263.     }
  264.     return ret;
  265. };
  266.  
  267.  
  268. // aka. swap sort
  269. var bubbleSort = function(a) {
  270.     var fin = false;
  271.     for (var i = a.length-1; i > 0; --i) { // n-1 round
  272.         fin = true;
  273.         for (var j = 0; j != i; ++j) {
  274.             if (a[j] > a[j+1]) {
  275.                 a.swap(j, j+1);
  276.                 fin = false;
  277.             }
  278.         }
  279.         if (fin) { // already all sorted
  280.             break;
  281.         }
  282.     }
  283. };
  284.  
  285.  
  286. var selectionSort = function(a) {
  287.     for (var i = 0; i != a.length-1; ++i) {
  288.         var t = i; // min pos
  289.         // select minium to front
  290.         for (var j = i+1; j != a.length; ++j) {
  291.             if (a[j] < a[t]) {
  292.                 t = j;
  293.             }
  294.         }
  295.         a.swap(i, t);
  296.     }
  297. };
  298.  
  299.  
  300. var insertionSort = function(a) {
  301.     for (var i = 1; i != a.length; ++i) {
  302.         var t = a[i];
  303.         // insert current a[i] to front proper pos
  304.         for (var j = i; j > 0; --j) {
  305.             if (a[j-1] > t) {
  306.                 a[j] = a[j-1];
  307.             } else {
  308.                 break;
  309.             }
  310.         }
  311.         a[j] = t;
  312.     }
  313. };
  314.  
  315.  
  316. // aka. grouped insertion sort
  317. var shellSort = function(a) {
  318.     var d = Math.floor(a.length/2);
  319.     while (d) {
  320.         // insertion sort by d
  321.         for (var i = d; i != a.length; ++i) {
  322.             var t = a[i];
  323.             // insert current to proper pos
  324.             for (var j = i; j >= d; j -= d) {
  325.                 if (a[j-d] > t) {
  326.                     a[j] = a[j-d];
  327.                 } else {
  328.                     break;
  329.                 }
  330.             }
  331.             a[j] = t;
  332.         }
  333.  
  334.         d = Math.floor(d/2);
  335.     }
  336. };
  337.  
  338.  
  339. var mergeSort = function(a) {
  340.     var merge = function(l, m, r) {
  341.         var ret = [];
  342.         var x = l;
  343.         var y = m + 1;
  344.         while (x <= m && y <= r) {
  345.             if (a[x] <= a[y]) {
  346.                 ret.push(a[x]);
  347.                 ++x;
  348.             } else {
  349.                 ret.push(a[y]);
  350.                 ++y;
  351.             }
  352.         }
  353.  
  354.         // concat left
  355.         if (x > m) {
  356.             ret = ret.concat(a.slice(y, r+1));
  357.         } else { // y > r
  358.             ret = ret.concat(a.slice(x, m+1));
  359.         }
  360.  
  361.         // copy the result back
  362.         var j = 0;
  363.         for (var i = l; i <= r; ++i) {
  364.             a[i] = ret[j++];
  365.         }
  366.  
  367.         if (j != ret.length) {
  368.             console.log('Error', ret);
  369.         }
  370.     }
  371.  
  372.     var sort = function(l, r) {
  373.         if (l < r) {
  374.             var m = Math.floor((l+r)/2);
  375.             sort(l, m);
  376.             sort(m+1, r);
  377.             merge(l, m, r);
  378.         }
  379.     }
  380.  
  381.     sort(0, a.length-1);
  382. };
  383.  
  384.  
  385. var quickSortFirst = function(a) {
  386.     var qs = function(l, r) {
  387.         if (l < r) {
  388.             var m = l; // m is the last smaller element pos (swapable)
  389.             for (var i = l+1; i <= r; ++i) {
  390.                 if (a[i] < a[l]) { // take first a[l] as the middle value to divide
  391.                     ++m;
  392.                     a.swap(i, m);
  393.                 }
  394.             }
  395.             a.swap(l ,m); // put to middle
  396.             qs(l, m-1); // sort left
  397.             qs(m+1, r); // sort right
  398.         }
  399.     };
  400.  
  401.     qs(0, a.length-1);
  402. };
  403.  
  404.  
  405. var quickSortLast = function(a) {
  406.     var qs = function(l, r) {
  407.         if (l < r) {
  408.             var m = l; // m is the first bigger element pos (swapable)
  409.             for (var i = l; i <= r-1; ++i) {
  410.                 if (a[i] < a[r]) { // take last a[r] as the middle value to divide
  411.                     a.swap(i, m);
  412.                     ++m;
  413.                 }
  414.             }
  415.             a.swap(r ,m); // put to middle
  416.             qs(l, m-1); // sort left
  417.             qs(m+1, r); // sort right
  418.         }
  419.     };
  420.  
  421.     qs(0, a.length-1);
  422. };
  423.  
  424.  
  425. var heapSort = function(a) {
  426.     var shiftup = function(l, r) {
  427.         var j = r;
  428.         while (true) {
  429.             if (j <= l) {
  430.                 break;
  431.             }
  432.  
  433.             // the larger the upper
  434.             var p = Math.floor((j-1)/2); // father
  435.             if (a[p] >= a[j]) {
  436.                 break;
  437.             }
  438.             a.swap(p, j);
  439.             j = p;
  440.         }
  441.     };
  442.  
  443.     // build the max heap
  444.     for (var i = 1; i < a.length; ++i) {
  445.         // shift the last up
  446.         shiftup(0, i);
  447.     }
  448.  
  449.     var shiftdown = function(l, r) {
  450.         var j = l;
  451.         while (true) {
  452.             var p = 2*j+1; // left child
  453.             if (p > r) {
  454.                 break;
  455.             }
  456.  
  457.             // find the bigger child
  458.             if (p+1 <= r && a[p+1] > a[p]) {
  459.                 ++p;
  460.             }
  461.             if (a[j] >= a[p]) { // j is already the biggest among the three
  462.                 break;
  463.             }
  464.             a.swap(p, j);
  465.             j = p;
  466.         }
  467.     };
  468.  
  469.     // find max every time and rebuild heap
  470.     for (var i = a.length-1; i > 0; --i) {
  471.         a.swap(0, i); // swap the max to last
  472.         // shift first(top) down
  473.         shiftdown(0, i-1);
  474.     }
  475. };
  476.  
  477.  
  478. // aka. bucket sort
  479. var radixSort = function(a) {
  480.     // use LSD
  481.     var d = 1;
  482.     // get Nth digit
  483.     var dig = function(n, i) {
  484.         var ret = 0;
  485.         while (i--) {
  486.             ret = n%10;
  487.             n = Math.floor(n/10);
  488.         }
  489.         return ret;
  490.     };
  491.  
  492.     while (true) {
  493.         var b = [];
  494.         var go = 0;
  495.  
  496.         for (var i = 0; i != a.length; ++i) {
  497.             var j = dig(a[i], d);
  498.             if (b[j] == undefined) {
  499.                 b[j] = [];
  500.             }
  501.             b[j].push(a[i]);
  502.             go = go || j;
  503.         }
  504.  
  505.         if (!go) {
  506.             break;
  507.         }
  508.  
  509.         // collect
  510.         a = [];
  511.         for (var k = 0; k != b.length; ++k) {
  512.             if (b[k] != undefined) {
  513.                 a = a.concat(b[k]);
  514.             }
  515.         }
  516.         ++d;
  517.     }
  518.  
  519.     return a;
  520. };
  521.  
  522.  
  523. var radixStrSort = function(a) {
  524.     // use MSD, recursive forward
  525.     var d = 0;
  526.     var rss = function(arr, dd) {
  527.         var b = [];
  528.         for (var i = 0; i != arr.length; ++i) {
  529.             // get d-th char
  530.             var j = 0;
  531.             if (dd < arr[i].length) {
  532.                 j = arr[i][dd].charCodeAt();
  533.             }
  534.  
  535.             if (b[j] == undefined) {
  536.                 b[j] = [];
  537.             }
  538.             b[j].push(arr[i]);
  539.         }
  540.  
  541.         //console.log(dd, b);
  542.  
  543.         arr = [];
  544.         for (var k = 0; k != b.length; ++k) {
  545.             // collect
  546.             if (b[k] != undefined) {
  547.                 // recursive sort if more than 1
  548.                 if (b[k].length > 1) {
  549.                     b[k] = rss(b[k], dd+1);
  550.                 }
  551.  
  552.                 arr = arr.concat(b[k]);
  553.             }
  554.         }
  555.         return arr;
  556.     }
  557.     a = rss(a, d);
  558.     return a;
  559. };
  560.  
  561.  
  562. // test main
  563. (function() {
  564.     var ret, a;
  565.  
  566.     console.log('=== find same elements ===');
  567.     ret = findSameElements([1,2,3,4,5,7,9,10], [3,4,7,10,12,13]);
  568.     console.log('Result:', ret);
  569.  
  570.     console.log('=== fibonacci recursive ===');
  571.     for (var i = 0; i <= 10; ++i) {
  572.         console.log(fibonacci(i));
  573.     }
  574.  
  575.     console.log('=== find 2nd max ===');
  576.     ret = find2ndMax([7,-6,7,7,7]);
  577.     console.log('Result:', ret);
  578.  
  579.     console.log('=== max subsequence sum ===');
  580.     ret = maxSubseqSum([-2,11,-4,13,-5,-2,8]);
  581.     console.log('Result:', ret);
  582.  
  583.     console.log('=== all arranges ===');
  584.     allRanges([1,2,3,4]);
  585.  
  586.     console.log('=== Greatest Common Divisor & Least Common Multiple ===');
  587.     gcdAndLcm(6, 9);
  588.  
  589.     console.log('=== matrix radio ===');
  590.     matrixRadio(9);
  591.  
  592.     console.log('=== matrix round ===');
  593.     ret = matrixRound(9);
  594.     for (var i = 0; i != 9; ++i) {
  595.         console.log(ret[i]);
  596.     }
  597.  
  598.     console.log('=== star & dot ===');
  599.     starDot(9);
  600.  
  601.     console.log('=== is primer ===');
  602.     ret = isPrimer(437);
  603.     console.log('Result:', ret);
  604.  
  605.     console.log('=== josephus ===');
  606.     josephus(3);
  607.  
  608.     console.log('=== find the middle value ===');
  609.     ret = findMiddle(1,-2,3);
  610.     console.log('Result:', ret);
  611.  
  612.     console.log('=== decimal to binary ===');
  613.     ret = dec2bin(9);
  614.     console.log('Result:', ret);
  615.  
  616.     console.log('=== binary search ===');
  617.     ret = binarySearch(8);
  618.     console.log('Result:', ret);
  619.  
  620.     // Sorting Ref: http://en.wikipedia.org/wiki/Sorting_algorithm
  621.     a = produceRamdomArray(10000, 6);
  622.     console.time('=== internal sort ===');
  623.     a.sort(function(a, b) { return a - b;}); // internal sort as number
  624.     console.timeEnd('=== internal sort ===');
  625.     checkSort(a);
  626.  
  627.     a = produceRamdomArray(10000, 6);
  628.     console.time('=== bubble sort ===');
  629.     bubbleSort(a);
  630.     console.timeEnd('=== bubble sort ===');
  631.     checkSort(a);
  632.  
  633.     a = produceRamdomArray(10000, 6);
  634.     console.time('=== selection sort ===');
  635.     selectionSort(a);
  636.     console.timeEnd('=== selection sort ===');
  637.     checkSort(a);
  638.  
  639.     a = produceRamdomArray(10000, 6);
  640.     console.time('=== insertion sort ===');
  641.     insertionSort(a);
  642.     console.timeEnd('=== insertion sort ===');
  643.     checkSort(a);
  644.  
  645.     a = produceRamdomArray(10000, 6);
  646.     console.time('=== shell sort ===');
  647.     shellSort(a);
  648.     console.timeEnd('=== shell sort ===');
  649.     checkSort(a);
  650.  
  651.     a = produceRamdomArray(10000, 6);
  652.     console.time('=== merge sort ===');
  653.     mergeSort(a);
  654.     console.timeEnd('=== merge sort ===');
  655.     checkSort(a);
  656.  
  657.     a = produceRamdomArray(10000, 6);
  658.     console.time('=== quick sort first ===');
  659.     quickSortFirst(a);
  660.     console.timeEnd('=== quick sort first ===');
  661.     checkSort(a);
  662.  
  663.     a = produceRamdomArray(10000, 6);
  664.     console.time('=== quick sort last ===');
  665.     quickSortLast(a);
  666.     console.timeEnd('=== quick sort last ===');
  667.     checkSort(a);
  668.  
  669.     a = produceRamdomArray(10000, 6);
  670.     console.time('=== heap sort ===');
  671.     heapSort(a);
  672.     console.timeEnd('=== heap sort ===');
  673.     checkSort(a);
  674.  
  675.     a = produceRamdomArray(10000, 6);
  676.     console.time('=== radix sort ===');
  677.     a = radixSort(a);
  678.     console.timeEnd('=== radix sort ===');
  679.     checkSort(a);
  680.  
  681.     a = produceRamdomStrArray(10000, 6);
  682.     console.time('=== internal string sort ===');
  683.     a.sort(); // internal sort as string
  684.     console.timeEnd('=== internal string sort ===');
  685.     checkSort(a);
  686.  
  687.     a = produceRamdomStrArray(10000, 6);
  688.     //a = ['cbda','cbad','cbbb','cb','cbb','cba','abc','bac']; // special case
  689.     console.time('=== radix string sort ===');
  690.     a = radixStrSort(a);
  691.     console.timeEnd('=== radix string sort ===');
  692.     checkSort(a);
  693. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement