Problem overview
The method printPowers(_ A: Int, _ B: Int) receives two non-negative integers and prints, one per line, every power of A that is less than or equal to B, starting at A⁰ = 1. It returns nothing: the result is the text it prints.
For A = 3 and B = 100 the output is 1, 3, 9, 27 and 81. The next power, 243, is larger than 100, so printing stops.
Approach
You don't need an exponent or a power function. Each power is the previous one multiplied by A: 1, then 1 * 3 = 3, then 3 * 3 = 9. So keep one variable holding the current power. While it is at most B, print it and multiply it by A. The first value that exceeds B fails the loop condition, and the loop ends. Because the powers only grow, no later power can be small enough to print.
Step by step
- Declare
powerwithvarand set it to 1. It changes on every iteration, so it can't be alet. Starting at 1 meansA⁰is the first candidate. - Write a
whileloop whose condition ispower <= B. Swift needs no parentheses around the condition, but the braces are required. - Print
powerinside the loop withprint, which ends each output with a newline. - Move to the next power with
power *= A. Without this line the loop would print 1 forever.
The solution in Swift
class Solution {
func printPowers(_ A: Int, _ B: Int) {
var power = 1
while power <= B {
print(power)
power *= A
}
}
}
Swift details:
- The underscores in the signature mean the arguments are passed without labels:
Solution().printPowers(3, 100). Intis 64 bits. If a power would pass its maximum,power *= Adoesn't wrap around quietly: the program traps and crashes. WithBnear the maximum, the last multiplication could overflow.- The method has no return type, so it returns
Void, and it only prints.
Tracing the loop
For A = 3 and B = 100, the loop moves through these states:
| Check | power at the check | Result |
|---|---|---|
| 1 | 1 | true: print 1, then power becomes 3 |
| 2 | 3 | true: print 3, then power becomes 9 |
| 3 | 9 | true: print 9, then power becomes 27 |
| 4 | 27 | true: print 27, then power becomes 81 |
| 5 | 81 | true: print 81, then power becomes 243 |
| 6 | 243 | false: the loop ends |
The loop always computes one power beyond the last one printed. That is harmless here, but it is why the overflow caveat above concerns values close to the largest Int.
Why this is a while loop
A for loop fits when you know the number of iterations in advance. Here the count depends on the values: it is the number of times you can multiply 1 by A before passing B, which is roughly the logarithm of B in base A. A while loop states the real stopping rule, "keep going while the power fits", so it is the natural choice. The loop runs about the logarithm of B in base A times, far fewer than B, so you don't need to test every number up to B.
Edge cases and common mistakes
Bsmaller than 1. WithB = 0the condition is false at the start, so nothing is printed. This is correct, sinceA⁰ = 1is already greater than 0.B = 1. Only1is printed, because the next power,A, is at least 2 whenA >= 2.A = 0. The loop prints 1, thenpowerbecomes 0 and stays 0, which is always at mostBwhenBis non-negative, so the loop never ends and prints 0 forever.A = 1loops forever as well, printing 1 each time. Running the loop with these values and a positiveBshows an endless stream of output.- Printing before the check. Multiplying first and printing afterwards would skip 1 and print a power larger than
B. - Using
<instead of<=. ForA = 3andB = 81, it would leave out 81.
Testing
printPowers(3, 100)prints 1, 3, 9, 27, 81.printPowers(2, 1)prints 1.printPowers(2, 0)prints nothing.
