hmit
hmit

Reputation: 152

Math crossing out

I am looking to play around with probability that involves a lot if big numbers. To save computing time, I was thinking about having the computer cross out terms like you do in regular math. For example:

(2*3*7*3) / (3*2*3*3)

Can be simplified to 7/3

If I were to create a Javascript function and pass it two arrays containing multiplication numbers to cross out, how would I go about doing this?

Just to be clear:

If I passed in [3, 4, 6, 4] and [4, 7, 3, 2], it would return two arrays: [4, 6] and [7, 2]

Upvotes: 3

Views: 108

Answers (5)

Maurice Perry
Maurice Perry

Reputation: 32831

Yes, or:

var arr1 = [5,2,3,7,8];
var arr2 = [3,5,2,3];
arr1.sort();
arr2.sort();
var i = 0, j = 0;
while (i < arr1.length && j < arr2.length) {
    if (arr1[i] < arr2[j]) {
        ++i;
    } else if (arr1[i] > arr2[j]) {
        ++j;
    } else {
        arr1.splice(i, 1);
        arr2.splice(j, 1);
    }
}
alert(arr1.toString() + "/" + arr2.toString());

UPDATE: to display a fraction

function prod(arr) {
    var res = 1, i;
    for (i = 0; i < arr.length; ++i) {
        res *= arr[i];
    }
    return res;
}

alert(prod(arr1) + "/" + prod(arr2));

Upvotes: 2

SRB
SRB

Reputation: 1111

If you do not require cancellation beyond exact numbers, this should do:

var x = [3, 4, 6, 4];
var y = [4, 7, 3, 2];
for(var i in x)
{
  for(var j in y)
  {
    if(x[i]==y[j])
    {
      x.splice(i,1);
      y.splice(j,1);
    }
  }
}
console.log(x);
console.log(y);

But in case you are interested in further cancellation take this:

var x = [3, 4, 6, 4];
var y = [4, 7, 3, 2];
for(var i in x)
{
  for(var j in y)
  {
    if(x[i]%y[j] == 0)
    {
      if(x[i]/y[j] > 1)
      {
        x[i] = x[i]/y[j];
      }
      else{
        x.splice(i,1);
      }
      y.splice(j,1);
    }
  }
}

console.log(x);
console.log(y);

Upvotes: 2

jdphenix
jdphenix

Reputation: 15435

Here's a method to do this that has no dependencies. There's a couple of assumptions made that might bite you.

  • It tests numbers based on equality. In your use case (probability), this will bite on floating point values.

  • It might just be better to run the calculations. For all we know the JavaScript engine of choice is doing better optimizations anyhow.

Here's the code and example usage:

var numerator = [2,3,7,3],
denominator = [3,2,3,3],
numerator2 = [3,4,6,4],
denominator2 = [4,7,3,2];

function simplify(num, den) {
  var value = {
    numerator: num.slice(),
    denominator: den.slice()
  },
  done = false,
  remove = function (a, b) {
    for (var aIdx = 0; aIdx < a.length; aIdx++) {
      for (var bIdx = 0; bIdx < b.length; bIdx++) {
        if (a[aIdx] === b[bIdx]) {
          a.splice(aIdx, 1);
          b.splice(bIdx, 1);
          return;
        }
      }
    }
    done = true;
  };
  while (!done) {
    remove(value.numerator, value.denominator);
  }
  return value;
}

simplify(numerator, denominator);
simplify(numerator2, denominator2);

Upvotes: 1

Christian
Christian

Reputation: 19750

Another method is to use a version of inArray (taken from jQuery), then check each element and remove elements as necessary. I'm not sure how well this would perform compared to just doing the calculations though, it would be worth testing on jsPerf.

For example:

removeDuplicates([3, 4, 6, 4], [4, 7, 3, 2]);

function removeDuplicates( array_1, array_2 ) {
    array_1.forEach(function(value, index) {
        var in_array = inArray( value, array_2 );
        if ( in_array !== false ) {
            array_1.splice( index, 1 );
            array_2.splice( in_array, 1 );
        }
    });

    console.log(array_1); // [4, 6]
    console.log(array_2); // [7, 2]
}

// from jQuery
function inArray(needle, haystack) {
    var length = haystack.length;
    for(var i = 0; i < length; i++) {
        if(haystack[i] == needle) return i;
    }
    return false;
}

jsFiddle: http://jsfiddle.net/tj6crcdt/

Upvotes: 2

hmit
hmit

Reputation: 152

After doing quite a bit of more research I found a way of doing it.

var arr1 = [5,2,3,7,8];
var arr2 = [3,5,2,3];
var extraVals = _.intersection(arr1,arr2);
var arr1Simp = _.difference(arr1, extraVals);
var arr2Simp = _.difference(arr1, extraVals);

Or as a function

var likeTerms = function(num, down){
    var extraVals = _.intersection(num,down);
    var numSimp = _.difference(num, extraVals);
    var downSimp = _.difference(down, extraVals);

    if(numSimp.length==0){
        numSimp.push(1);
    }
    if(downSimp.length==0){
        downSimp.push(1);
    }
    return {
        num: numSimp,
        down: downSimp
    };
};

Demo

Upvotes: 0

Related Questions