Trying to optimize nested loops

Just doing some generic experiments, related to this challenge

Have this little example:

// To get array of all possible multiplications of i and j, without repeating results
// for i = 1, 2, 3
// for j = 1, 2, 3
let allMults = [];
for (let i = 1; i < 4; i++) {
  for (let j = 1; j < 4; j++) {
    if (allMults.includes(i*j) == false) {
      allMults.push(i*j);
    }
  }
}

console.log(allMults);//[ 1, 2, 3, 4, 6, 9 ]

But I have a suspicion that there should be more elegant approach than nested loops, although struggling to express my thoughts properly, I just see that math here is so… simmetrical i guess.
Interested in general case where sequences of numbers i and j are identical.

Also have a question about code structure.

In solution above I have:

    if (allMults.includes(i*j) == false) {
      allMults.push(i*j);

What if I instead do something like this:

    let oneMult = i * j;
    if (allMults.includes(oneMult) == false) {
      allMults.push(oneMult);

Would it be the better option? I understand this as tradeoff ‘declare one variable to get one multiplication instead of two.’

You can use a set, includes is an extra loop, making your algorithm do an extra nested loop

Thanks for your suggestion.
I think I’ve never used set before. This link to MDN is relevant to your advice? If no, would you be so kind to provide some useful links?
UPDATE: I believe I found what I need on MDN, thanks again!

Yeah, for the purpose of the challenge your advice is great!

If I’ll try to get more abstract conclusion from it:

If I need to get final result as integer

I don’t need to store any temporary results in more complex data structures

I need just to store temporary result as integer.

However, I am wondering about process of generating temporary results.
Below, all possible multiplications for i = 1, 2, 3 and identical sequence of numbers j

1 2 3
1 1 2 3
2 2 4 6
3 3 6 9

As we see, central diagonal (1, 4 ,9) - it’s quadratic numbers.
All multiplications above central diagonal which are(2, 3, 6) are identical
to multiplications below central diagonal which are also (2, 3, 6).

So I believe, if I see such mathematical pattern, I can optimize method of generating multiplications.
Now I am doing:

for (let i = 1; i < 4; i++) {
  for (let j = 1; j < 4; j++) {
    tempResult = i*j;
  }
}

So my issue is - could I apply mathematical patterns from the table above to my solution and make something more efficient than this two nested loops?

I am not sure what knowledge/skills I need to acquire to move in such direction?

I mean all results above central diagonal. Central diagonal is (1,4 ,9).
All results above it is (2,3,6)

Right now I am not concerned about check for palindrome.

Before I will check ‘if number is palindrome’, I need to generate that number.
In example above I have nested loops, these loops will generate 9 results total.

If I take a close look at this results: (2,3,6,1,4,9,2,3,6)
I see mathematical pattern. See which results are repeating? There may be the way to use this pattern in actual code.

I wanna to come up with implementation which will allow to reduce number of checks in the first place.

If my explanation is still not clear, I will implement solution of the actual challenge, will comment it properly, and will express my logic in that context.

Instead of let j = 1 try let j = i

1 Like

That actually was it! I believe this approach is scalable and will work when applied to actual challenge.
Do you have any advice for me to get better when trying to optimize something like this?

Just keep practicing! Now you have this trick in your toolbelt.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.