Object/debugging weirdness [Smallest Common Multiple]

Object/debugging weirdness [Smallest Common Multiple]
0

#1

I’m trying to solve this problem in an inefficient but easy to understand way: store the prime factors of all numbers in the range as objects eg for 12 = 2^2 * 3 :
{ 2: 2, 3: 1 }
Then form the answer as the product of these prime factors raised to the highest power needed to form any individual number in the range. eg if the ‘range’ - not contiguous here for illustrative purposes - included just 8, 9 in addition to 12 :
{ 2: 3 }
{ 3: 2 }

The answer is:
{ 2: 3, 3: 2 } = 72

Console logging is showing me that lcmf object - which I want to watch building up these factors - is fully populated even though it was just declared in the previous line, eg
var lcmf = {};

I tried running the code directly in the browser with the same result. This is is making debugging impossible & me very confused - so thanks for having a look.

Here’s the code:

function testPrime(primes, p) {
  return primes.every(function(el){
    //console.log(p, el, p%el, p%el==0);
    return p%el != 0;
    } 
  );
}

function listPrimes(mx) {
  var res = [];
  var primes = [2];
  for (var i=2; i<=mx; i++){
    if (testPrime(primes, i)) {
      primes.push(i);     
    }
  }
  return primes;
}

function primeFac(primes, p){
  PFO = { }; // prime factor object
  var n = 0;
  for (var i=primes.length-1; i>=0; i--) {
    while (p%primes[i]==0){
      n += 1;
      p /= primes[i];
    }
    if (n>0) {
      PFO[primes[i]] = n;
    }
    n = 0;
  }
  //console.log(PFO);
  return PFO;
}

function smallestCommons(arr) {
  var l = Math.max(arr[0], arr[1]);
  var s = Math.min(arr[0], arr[1]);
  var lcmf = {}; // LCM factor object
  console.log("lcmf>>", lcmf);
      
  var PFOs = [];
  var primes = listPrimes(l);
  
  console.log(l, s, "primes:", primes, lcmf, PFOs, "...");
  for (i=l; i>=s; i--){
    PFOs.push(primeFac(primes,i));
  }
  console.log("<", lcmf);
  for (i=0; i<PFOs.length; i++){
    console.log(i, lcmf, PFOs[i]);
    for (var k in PFOs[i]) {
      if (lcmf.hasOwnProperty(k)){
        lcmf[k] = Math.max(PFOs[i][k], lcmf[k]);
      } else {
        lcmf[k] = PFOs[i][k];
      }
    }
    console.log("->", lcmf);
  }
  console.log("--------------------------------------");
  return 1; // need to take product of powered factors
}

smallestCommons([1, 13]);

#2

The reason is that console.log prints a reference to the object and when you check it, the browser shows you its current value, not the one it had when you called console.log.

See https://stackoverflow.com/questions/7389069/how-can-i-change-the-default-behavior-of-console-log-in-safari for more explanation.

Replacing lcmf with JSON.parse(JSON.stringify(lcmf)) in all calls to console.log should solve your problem.


#3

Thanks - that was really confusing me!

Perhaps the section on OO/FP should draw attention this? For me at least it seems very odd…