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
- Create the running power. Declare
powerwithvarand the value 1, sinceA⁰ = 1. It must be avarbecause the loop changes it, and Kotlin infers the typeIntfrom the value. - 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 aboveBis never printed. - Print the current power with
println, which also moves to a new line, as the output format needs. - Move to the next power. Set
powertopower * Awith 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:
varversusval.valcan't be reassigned, so a value that changes on every pass needsvar. Usingvalhere gives a compile error atpower *= A.*=is shorthand forpower = power * A.- Syntax. The condition goes in parentheses after
whileand 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
Bsmaller than 1. WithB = 0the condition is false on the first check and nothing is printed, because evenA⁰ = 1is above the limit.A = 1. Every power of 1 is 1, sopowernever grows pastBand the loop prints1forever whenB ≥ 1. The same happens forA = 0, wherepowerbecomes 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
Ainstead of 1. That skipsA⁰ = 1, and the output forA = 3,B = 100would lose its first line. - Multiplying before printing. The first line would be
A, and the last printed number could be aboveB. - Overflow near the top of the
Intrange.Inthas 32 bits and overflow wraps silently. WithA = 2andB = Int.MAX_VALUE, the power after1073741824is-2147483648, which is still<= B, and the loop goes on printing wrong values. UseLongforpowerifBcan be that large. - Forgetting the update. A loop that never changes
powernever ends.
Testing
A = 3,B = 100prints1,3,9,27,81.A = 2,B = 0prints nothing.A = 5,B = 1prints1.A = 2,B = 16prints1,2,4,8,16: a power equal toBis included, because the condition uses<=.