Start learning free

LESSON 161 OF 348 · LOOPS - CHALLENGES

Print Powers in Kotlin: A while Loop Solution

Practice Read the full explanation

Given two non-negative integers A and B, print to the console all numbers less than or equal to B that are powers of A

Powers of a number are: A0, A1, A2, etc.

An = A multiplied by itself n times

A0 = 1
A1 = A
A2 = A * A
A3 = A * A * A
A4 = A * A * A * A
etc.

Example:

Input: A = 3, B = 100

Output:
1
3
9
27
81

Explanation:
30 = 1
31 = 3
32 = 9
33 = 27
34 = 81
Hints:

We start with the integer 1. We should repeatedly do some instructions (print it then multiply it by A) as long as one condition is satisfied (current power <= B). Sounds familiar?

We should use a variable power, initially equal to 1, in order to store the current power. And we should use a while loop to repeatedly check if power <= B and if so, print and update power. How will the code look like?

power = 1
while power <= B:
	print(power)
	power *= A


STEP 1 OF 4
    Ctrl + Enter to check

    KOTLIN · LOOPS - CHALLENGES

    Print Powers in Kotlin, explained

    Problem overview

    The function printPowers(A: Int, B: Int) receives two non-negative integers. It must print every power of A that is less than or equal to B, one per line, in increasing order. The powers are A⁰ = 1, A¹ = A, A² = A * A and so on.

    For A = 3 and B = 100 the output is 1, 3, 9, 27 and 81, each on its own line. The next power, 3⁵ = 243, is above 100, so it isn't printed. The function returns nothing: its job is to print.

    Approach

    Each power is the previous power multiplied by A. So there is no need for an exponent function or a count of how many powers exist. Keep one variable that holds the current power, starting at 1. As long as it is not larger than B, print it and multiply it by A to get the next one.

    The number of repetitions isn't known in advance, which makes this a job for a while loop and its condition rather than a for loop over a fixed range.

    Step by step

    1. Create the running power. Declare power with var and the value 1, since A⁰ = 1. It must be a var because the loop changes it, and Kotlin infers the type Int from the value.
    2. Write the loop with its condition. while (power <= B) keeps the loop going as long as the current power is within the limit. The condition is checked before every pass, so a power above B is never printed.
    3. Print the current power with println, which also moves to a new line, as the output format needs.
    4. Move to the next power. Set power to power * A with the *= operator. Without this line the condition would never change and the loop would print the same number forever.

    The solution in Kotlin

    class Solution {
        fun printPowers(A: Int, B: Int) {
            var power = 1
            while (power <= B) {
                println(power)
                power *= A
            }
        }
    }
    

    A few Kotlin details:

    • var versus val. val can't be reassigned, so a value that changes on every pass needs var. Using val here gives a compile error at power *= A.
    • *= is shorthand for power = power * A.
    • Syntax. The condition goes in parentheses after while and the body in braces. No semicolons are needed.
    • The function has no return type. A Kotlin function without one returns Unit, which is why the signature ends right after the parameters.

    Complexity

    Time: O(log B). For A ≥ 2 the power is multiplied by at least 2 on every pass, so it passes B after about log base A of B iterations. For B = 100 and A = 3 that is 5 passes.

    Space: O(1). The function uses one extra variable, power.

    Edge cases and common mistakes

    • B smaller than 1. With B = 0 the condition is false on the first check and nothing is printed, because even A⁰ = 1 is above the limit.
    • A = 1. Every power of 1 is 1, so power never grows past B and the loop prints 1 forever when B ≥ 1. The same happens for A = 0, where power becomes 0 after the first pass and stays there. Both are non-negative, so a program that must handle them needs a special case before the loop, for example printing 1 once and returning.
    • Starting at A instead of 1. That skips A⁰ = 1, and the output for A = 3, B = 100 would lose its first line.
    • Multiplying before printing. The first line would be A, and the last printed number could be above B.
    • Overflow near the top of the Int range. Int has 32 bits and overflow wraps silently. With A = 2 and B = Int.MAX_VALUE, the power after 1073741824 is -2147483648, which is still <= B, and the loop goes on printing wrong values. Use Long for power if B can be that large.
    • Forgetting the update. A loop that never changes power never ends.

    Testing

    • A = 3, B = 100 prints 1, 3, 9, 27, 81.
    • A = 2, B = 0 prints nothing.
    • A = 5, B = 1 prints 1.
    • A = 2, B = 16 prints 1, 2, 4, 8, 16: a power equal to B is included, because the condition uses <=.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free