Code Challenges: Intermediate Javascript excercise 5: how does the "while loop" work?

I was able to pass this exercise by changing the variable name in the “while loop”, however I don’t understand the mechanics behind how it searches for the “smallest power of two greater than the given number”.

Additionally, I’m not sure why the two duplicate variable names were altering the result.

exercise instructions:

"We wrote a function, smallestPowerOfTwo() , which takes in an array.

Within our function, we create a new array called results . We then loop through the argument array and calculate the smallest power of two which is greater than the current element before using .push() to add it to results .

It’s not doing what we want. Can you fix our code, please?"

Can anyone explain how the code below searches for the smallest power of 2 greater than the given number?

// The ‘inner’ while loop - searches for smallest power of 2 greater than the given number

let n = 1;
while (n < number) {
n = n * 2;

full solution code below:

const numbers = [5, 3, 9, 30];

const smallestPowerOfTwo = arr => {
let results = ;
// The ‘outer’ for loop - loops through each element in the array
for (let i = 0; i < arr.length; i++) {
let number = arr[i];

        // The 'inner' while loop - searches for smallest power of 2 greater than the given number
        let n = 1;
        while (n < number) {
              n = n * 2;
        }
        results.push(n);
  }
  return results

}

console.log(smallestPowerOfTwo(numbers))
// Should print the returned array [ 8, 4, 16, 32 ] instead prints the returned array [8]

Any thoughts are appreciated!

Is that the provided solution, or your working code? It gives the correct results.

Hi Roy! That is my working code - and it does give the correct results, I just don’t understand why. Specifically, I am having difficulty understanding how the syntax of the while loop works, and how it manages to search for the smallest power of 2 greater than the given number.

Hey David

Here’s the code of the challenge:

const numbers = [5, 3, 9, 30]; const smallestPowerOfTwo = arr => { let results = []; // The 'outer' for loop - loops through each element in the array for (let i = 0; i < arr.length; i++) { number = arr[i]; // The 'inner' while loop - searches for smallest power of 2 greater than the given number let j = 1; while (j < number) { j *= 2; } results.push(j); } return results } console.log(smallestPowerOfTwo(numbers)) // Should print the returned array [ 8, 4, 16, 32 ] instead prints the returned array [8]

What this is doing is the following:

  • pass an array with numbers
  • for each number assign to a variable j the initial value 1
  • verify that the value of j is currently less than the value of number (element of the array numbers), meaning:
    j=1
    number=5
    j<number is true so multiply j times 2
    j=2
    number=5
    j<number is true so multiply j times 2
    j=4
    number=5
    j<number is true so multiply j times 2
    j=8
    number=5
    j<number is false so push j to the return array.

Move to the next i and repeat.

Hopefully this was clear enough :slight_smile: Does this help?

Edit:
I realised it was not very clear, now it should be! :wink:

1 Like

Hi @usernamegiapreso, thanks for sharing this example! So, I think I may be having difficulty understanding how the fundamentals of a while loop work.

I’ll go through my faulty logic, using your example starting with the first case, where we assign an initial value of 1 to j.

j=1
number=5
j<number is true so multiply j times 2

so, I understand that 1 is less than 5, making the statement true, and therefore we multiply j times 2. However, if j = 1, why aren’t we multiplying 1 times 2, and getting a result of 2? how do we get a result of 8?

This is an infinite loop:

while (true) {

}

It will go on into perpetuity unless the system intervenes and halts the program. We prevent infinite loops by giving the code body a breaking condition:

while (true) {
    if (Math.random() > 0.9) {
        break;
    }
}

A while loop functions with any condition, not just numbers. So long as the condition is met, the loop continues to interate.

The above loop keeps doubling the value of n until it is greater than number. 8 fails the condtion, n < number when number is 5.

8 is 2 to the 3. The loop is effectively multiplying n by 2, three times.

1 * 2 * 2 * 2

Ah, it just clicked. I’m tracking now!

1 Like

Since this was a challenge, it stands as an opportunity to learn something new from what you so far know, or from extending your knowledge base with extra study.

Consider the following, but leave it for now, and just see it as a sneak peek at some of the goodies still to come up…

const numbers = [5, 3, 9, 30];
const smallestPowerOfTwo = arr => arr.map(m => 2 ** Math.ceil(Math.log(m)/Math.log(2)));
console.log(smallestPowerOfTwo(numbers))
[ 8, 4, 16, 32 ]

The function, an expression, has a return expression that maps the results of the callback expression. It follows a functional approach based upon expressions (values).

The only thing new is the Array method, .map(), but more importantly, higher-order functions have not yet come up. Both roughly coincide each other in the curriculum. All in good time. This should give you an idea of how we can abstract from the original code a whole new solution.

Bottom line, as we delve deeper into the language, the more it allows us to implement our knowledge of Maths into our code design. With practice you’ll soon be able to rewrite code in several forms yet arrive at the same results. Keep this idea stored as you progress.

For instance, in the exercise code, the outer loop uses counting and an index. Since the array is never mutated, we could dispose of that approach and go straight to the values, using for..of.

for (let m of arr) {
    let n = 1
    while (n < m) {
        n *= 2
    }
    results.push(n)
}

Are we improving code when we re-write it? Rhetorical question, really. At this point it is enough to learn other ways of doing roughly the same thing. My little snippet above is not the only, or likely the best solution. It is a solution that approaches the problem from a different perspective taking a different line.

The goal is what is important. Meet that goal and from there you’ll eventually be faced with choosing a line that favors readability, minimum time and space complexity, and maintainability. Not goals we need to set for ourselves, today. The day will come. Let these little ideas stick and see where they take you.

Happy coding!

Thank you for sharing this Roy! Boy, I am totally lost haha. I’m going to spend the next week going back over the fundamentals of Javascript taught in earlier CodeCademy modules and then return and see if I can make headway with this.

1 Like

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