U
U
Umid2017-09-16 14:21:18
JavaScript
Umid, 2017-09-16 14:21:18

How can the fraction reduction algorithm be optimized?

Good afternoon.
I decided to reduce fractions by dividing them by prime numbers from 2 to the minimum value between the numerator and denominator (i.e. if the numerator is greater than the denominator, then we take all prime numbers from 2 to the denominator, and vice versa).
Finding prime numbers implemented through the "Sieve of Eratosthenes". All found prime numbers remain in the simpleNumbers array, for optimization purposes, because the fraction reduction function is used repeatedly.

var simpleNumbers = [2, 3];
function getSimpleNumbers(limit) {
  var i = (simpleNumbers.length == 0) ? 0 : simpleNumbers[ simpleNumbers.length - 1 ];

  if( i > limit ) {
    for (var k = 0; ; k++) {
      if( simpleNumbers[k] > limit ) {
        return simpleNumbers.slice(0, k);
        break;
      }
    }
  }

  for (; i <= limit; i++) {
    var flag = true;

    for (var j = 0; j < simpleNumbers.length; j++) {
      if( i % simpleNumbers[j] == 0 ) {
        flag = false;
        break;
      }			
    }		
    if( flag ) {
      simpleNumbers.push(i);
    }
  }


  return simpleNumbers;
}

// Функция принимает два аргумента и максимально сокращает их. 
// Функция возвращает объект с двумя свойствами n и d (числитель и знаменатель)
function reduceFrac(numerator, denomerator) {
  var frac = {
    n: numerator,
    d: denomerator
  }, s;

  if(Math.abs(frac.n) > Math.abs(frac.d)) {
    s = getSimpleNumbers( Math.abs(frac.d) );
  } else {
    s = getSimpleNumbers( Math.abs(frac.n) );
  }

  for (var i = 0; i < s.length; i++) {
    while(true) {
      if( Math.abs(frac.n % s[i]) == 0 && Math.abs(frac.d % s[i]) == 0 ) {
        frac.n /= s[i];
        frac.d /= s[i];
      } else {
        break;
      }
    }
  }
  return frac;
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
Rsa97, 2017-09-16
@Rsa97

Binary algorithm for calculating the greatest common divisor (gcd)

function nod(m, n) {
  var mult = 0;
  while (true) {
    if (0 == m) {
      return n << mult;
    }
    if (0 == n) {
      return m << mult;
    }
    if (1 == m || 1 == n) {
      return 1 << mult;
    }
    if (m == n) {
      return m << mult;
    }
    if (0 == (m & 1) && 0 == (n & 1)) {
      mult++;
      m >>= 1;
      n >>= 1;
    } else if (0 == (m & 1)) {
      m >>= 1;
    } else if (0 == (n & 1)) {
      n >>= 1;
    } else if (m > n) {
      m = (m-n) >> 1;
    } else {
      n = (n-m) >> 1;
    }
  }
}

function reduceFrac(numerator, denomerator) {
  var divider = nod(numerator, denomerator);
  return {n: numerator/divider, d: denomerator/divider};
}

J
jcmvbkbc, 2017-09-16
@jcmvbkbc

The classical solution is the search for GCD by Euclid's algorithm .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question