The Pairwise Algorithm Challenge

@dracoin My code was behaving erratically, and returning NaNs etc. Then I looked at your code and initialized searchVal, and for some reason, this fixed the problem…strange…? My code was exactly the same as yours, except for 1 thing - at first I didn’t bother to initialize searchValue, and instead just used arg - arr[element] inside the if statement. Anyway, here’s the code which failed…in case anyone wants to see indexes behaving erratically, inexplicably, which is what this scripting challenge is about…

function pairwise(arr, arg) {
  var sumOfIdx = 0;
  for (var i = 0; i < arr.length; i++) {
    if (arr.indexOf(arg - arr[i]) !== -1 && arr.indexOf(arg - arr[i]) !== i) { //i.e. the ith element has at least 1 pair
      sumOfIdx += i + arr.indexOf(arg - arr[i]);
      arr[i] = "-";
      arr[arr.indexOf(arg - arr[i])] = "-";
    }
  }  
  return sumOfIdx;
}

I don’t understand why pairwise([0, 0, 0, 0, 1, 1], 1) should return 10. The rules state that if “multiple pairs are possible that have the same numeric elements but different indices, return the smallest sum of indices.” None of the solutions above seem to be taking that rule into account.

Maybe I’m misinterpreting the rule?

0 0 0 0 1 1 // values
0 1 2 3 4 5 // indices
0       1   //= 4 * wouldn't this be the pair with the smallest sum of indices?
  0     1   //= 5 
    0   1   //= 6
      0 1   //= 7

0         1 //= 5 
  0       1 //= 6 
    0     1 //= 7
      0   1 //= 8
function pairwise(arr, arg) {
  
  var indices = [];
  
  for(var i=0; i<arr.length-1; i++){
    for(var j=i+1; j<arr.length; j++){
      if(indices.indexOf(i) > -1){
        break;
      }
      if(indices.indexOf(j) > -1){
        continue;
      }
      if(arr[i] + arr[j] === arg){
        indices.push(i, j);
      }
    }
  }
  
  if(indices.length === 0){
    return 0;
  }
  
  return indices.reduce(function(sum, value){
    return sum + value;
  });
      
}

I just used loop in reduce function to check the array and push needed indexes to new array. Then another reduce to sum new array of indexes.

function pairwise(arr, arg) {
  var indicesArr = [];
  arr.reduce(function(acc, currValue, currIndex){
    for (var i=0; i<arr.length; i++){
     if (arr[i] + currValue === arg && indicesArr.indexOf(i) === -1 && indicesArr.indexOf(currIndex) === -1 && i !== currIndex){
       return indicesArr.push(i, currIndex);
     }
    } 
  }, 0);
  var sum = indicesArr.reduce(function(a, b){
    return a + b;
}, 0);
  return sum;
}

Yeah that sentence is kind of confusing. It should really just state that indices cannot be used more than once, but elements of the same value can.

Here is my clean solution :smiley:

function pairwise(arr, arg) {
   var sum = 0;
   for (var j=0;j<arr.length;j++) {
     for (var i=j+1; i<arr.length;++i) {
         if(arr[i] + arr[j] == arg) {
           sum += i + j;
           arr[i] = 'a';
           arr[j] = 'b';
         }
       }
     }
  
return sum;
}

Mine got a little bit easier than the main solutions, and I could see that it ended up similar to some other solutions:

function pairwise(arr, arg) {
  const indexArr = [];

  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (!indexArr.includes(i) && !indexArr.includes(j) && arr[i] + arr[j] === arg) {
        indexArr.push(i, j);
      }
    }
  }
  
  if (indexArr.length > 0) {
    return indexArr.reduce((a, b) => a + b);    
  } else {
    return 0;
  }
}
1 Like

This is exactly the same answer I got! This one was fun.

function pairwise(arr, arg) {
  return arr.reduce((acc, num, i, a) => {
    let z = a.indexOf((arg-num), i+1)
    return z > 0 ? (a[z] = NaN, acc + i + z) : acc
  }, 0)
}
2 Likes

Is a good practice to use a copy of the arguments instead of modify it directly, like in the advanced solution? And if the arr.indexOf() is a slowest method than the normal for loop in which cases it is preferable to use it?