This Code Should Be Way Shorter IMO

Hello,

My code works, but I am unhappy with how many steps it took me to solve this problem.

Here is the original question:

Create a function divisibleByFivePairSum that takes an array of numbers.
It should return an array of all the pairs of indices whose sum is a multiple of five.

console.log(divisibleByFivePairSum([1, 5, 2, 0, 4]));
// should return [ [ 0, 4 ], [ 1, 3 ] ]

Here is my code:

function divisibleByFivePairSum(array){
  let result = [];
  
  //use a nested loop to iterate through every combo
  for (let i = 0; i < array.length; i++) {
    for (let j = 0; j < array.length; j++) {
      //initialize an empty subArray
      let temp = [];
      //skip if the same number is selected twice
      if (i === j) continue;
      //if divisible by 5, push to temp array
      if ((array[i] + array[j]) % 5 === 0) {
        temp.push(i, j)
        //sort temp and push to result
        temp.sort((a, b) => a - b);
        result.push(temp);
      }
    }
  }
  
  //sort the final result array by using string conversion
  result.sort((a, b) => a.toString().localeCompare(b.toString()));
 	
  //splice out repeated subArrs, again using string conversion
  for (let i = 0; i < result.length - 1; i++) {
    if (result[i].toString() === result[i + 1].toString()) {
      result.splice(i, 1);
    }
  }
  return result;
}

At first, my code was returning all possible combinations, like this:
[[0,4],[4,0],[1,3],[3,1] ...etc]

I needed to filter out equivalent pair subarrays or simply not push() them to result in the first place, but because you can’t just check if array.includes(subArr), I had to go through all these steps of saving all possible combinations, sorting them by converting the subArrays to strings, and then looping through and deleting repeated values.

[Another technique I used was using a for (let item of result) loop inside the main loop to check if item.toString() === temp.toString(), but that was also bulky and cumbersome.]

This was in an “easy” section, but honestly it gave me some trouble.

Any advice would be appreciated. I feel like this should be solvable in <10 lines.

Thank you.

Have you tried to find a way to not consider repeated pairs at the stage of generating them? Take a look at the i and j pairs from the loops:

i = 0 [0,0] [0,1] [0,2] [0,3] [0,4];
i = 1 [1,0] [1,1] [1,2] [1,3] [1,4];
        ^ repeated
i = 2 [2,0] [2,1] [2,2] [2,3] [2,4];
        ^     ^ repeated
i = 3 [3,0] [3,1] [3,2] [3,3] [3,4];
        ^     ^     ^ repeated
i = 4 [4,0] [4,1] [4,2] [4,3] [4,4];
        ^     ^     ^     ^ repeated

Notice with higher i, higher is the number of repeated pairs. Any ideas how that could be used?

1 Like

@sanity

Thank you for your advice. Here’s one way I did it.


function divisibleByFivePairSum(array) {
  let result = [];
  //use a nested loop to iterate through every combo
  for (let i = 0; i < array.length; i++) {
    for (let j = 0; j < array.length; j++) {
      //initialize an empty subArray
      let temp = [];
      //skip if the same number is selected twice
      if (i === j) continue;
      //if divisible by 5, push to temp array
      if ((array[i] + array[j]) % 5 === 0) {
        temp.push(i, j)
        //sort temp
        temp.sort((a, b) => a - b);
        //if result does not contain temp already, then push it
        if (!result.some(item => item[0] === temp[0] && item[1] === temp[1])) result.push(temp)
      }
    }
  }
  return result;
}

See if you can not have to sort it each time. This is not very efficient.

1 Like

@RandellDawson

Easy peasy, lemon squeezy into the eyes of your enemies.

function divisibleByFivePairSum(array){
  let result = [];
  for (let i = 0; i < array.length; i++) {
    for (let j = 0; j < array.length; j++) {
      let temp = [];
      if (i === j) continue;
      if ((array[i] + array[j]) % 5 === 0) {
        temp.push(i, j)
        if (i > j) temp.sort((a, b) => a - b);
        if (!result.some(item => item[0] === temp[0] && item[1] === temp[1])) result.push(temp)
      }
    }
  }
  return result;
}

And thank you for that feedback.

Still no need for sort with the if statement. Move the temp variable from above and do:

const temp = i > j ? [j, i] : [i, j];
1 Like

@RandellDawson

Ngl that was super slick. 3 lines condensed into 1.

@sanity

Ohmy I just realized what you were saying.

The j loop can start with j = i + 1.

You are a genius.

1 Like