Most efficient way to write Combination and Permutation calculator in Javascript

前端 未结 5 875
闹比i
闹比i 2021-01-12 10:05

I have a math website http://finitehelp.com that teaches students Finite Math. I thought it would be cool to include a calculator so I made one for combinations and permutat

相关标签:
5条回答
  • 2021-01-12 10:45

    I would prefer recursive function, tail recursive may cause stackoverflow for functions like fibonacci.

    Math._factorial = function(n){
      return Math._fact(n,1);
    }
    
    Math._fact= function(n,res){
      n = Number(n);
      if (n == null) {
        alert("Factorial requires a numeric argument.");
        return null;
      } else if (n < 2){
        return res;
      } else {
        return Math._fact(n-1, res*n);
      }
    }
    
    0 讨论(0)
  • 2021-01-12 10:46

    If you're concerned about efficiency, you'd probably want to re-implement the factorial as an iterative function rather than a recursive one. The recursive version will use a lot more memory and CPU time than the iterative version.

    function factorial(n) { 
      var x=1; 
      var f=1;
      while (x<=n) {
        f*=x; x++;
      }
        return f;
    }
    

    You also shouldn't be adding your own functions to the Math namespace. It's not a good habit to get into.

    0 讨论(0)
  • 2021-01-12 10:49

    Well, here we go!

    First of all, why would you ever need to write this?

    Math.divide = function(a,b)
    {
        return a/b;
    }
    

    I would do away with it completely.

    You can also clean up your Math.factorial a little bit:

    Math.factorial = function(n)
    {
        n = Number(n);
    
        if (isNAN(n)) {
            alert("Factorial requires a numeric argument.");
            return null;
        } else if (n < 2) {
            return 1;
        } else {
            return (n * Math.factorial(n - 1));
        }
    }
    

    But the main problem is your onclick() code:

    onclick="var n = T1.value; var r = T2.value; var n_minus_r = parseFloat(n) - parseFloat(r); var numerator = Math.factorial(T1.value); var n_minus_r_fact = Math.factorial(n_minus_r); var r_fact = Math.factorial(r); var denominator = n_minus_r_fact * r_fact; T3.value = Math.divide(numerator,denominator); return true;
    

    This is way too complicated. I'd make it a function and bind it to the element, which would get rid of all of the crap in your HTML and make it a bit easier to work with:

    window.onload = function()
    {
        document.getElementById('calculate').onclick = function() {
            var n = T1.value,
                r = T2.value;
    
            T3.value = Math.factorial(n) / (Math.factorial(r) * Math.factorial(n - r));
        }
    }
    

    And just get rid of the onclick= code.

    0 讨论(0)
  • 2021-01-12 11:03

    As we know, combinations is short for:

    So the fastest combinations implement is below:

    function factorial(n) {
      let r = 1;
      while (n > 1) r *= n--;
      return r;
    }
    function combinations(n,r){
        let s = 1;
        let i = r;
        while(i<n) s*=++i;
        return s/factorial(n-r)
    }
    combinations(5,2)
    
    
    0 讨论(0)
  • 2021-01-12 11:05
    Math.factorial= function(n){
        var i= n;
        while(--i) n*= i;
        return n;
    }
    
    Math.combinations= function(n, r, repeats){
        if(n< r) return 0;
        if(n=== r) return 1;
        if(repeats){
            return Math.factorial(n+r-1)/((Math.factorial(r)*Math.factorial(n-1)));
        }
        return Math.factorial(n)/((Math.factorial(r)*Math.factorial(n-r)));
    }
    
    
    var a= [
        'aqua', 'black', 'blue', 'fuchsia', 'gray', 'green', 'lime', 'maroon',
        'navy', 'olive', 'orange', 'purple', 'red', 'silver', 'teal', 'white',
        'yellow'
    ]
    //how many 3 color combinations are there?
    //[red,green,blue] is different than [green,red,blue]
    // Math.combinations(a.length,3,true) >>969
    // how many unique combinations (ignoring order) are there?
    // Math.combinations(a.length,3)>>680
    
    0 讨论(0)
提交回复
热议问题