Start learning free

LESSON 129 OF 414 · WHILE LOOPS & FOR LOOPS

Print Multiples in Scala: A While Loop with a Counter

Practice Read the full explanation

Given two positive integers A and B, print to the console the first A positive numbers that are divisible by B

A number X is divisible by B if X modulo B == 0

Example:

Input: A = 5, B = 3

Output:
3
6
9
12
15

Explanation:
The first 5 positive integers that are divisible by 3 are
3, 6, 9, 12 and 15
1 modulo 3 = 1 => not divisible
2 modulo 3 = 2 => not divisible
3 modulo 3 = 0 => divisible
4 modulo 3 = 1 => not divisible
5 modulo 3 = 2 => not divisible
6 modulo 3 = 0 => divisible
7 modulo 3 = 1 => not divisible
8 modulo 3 = 2 => not divisible
9 modulo 3 = 0 => divisible
10 modulo 3 = 1 => not divisible
11 modulo 3 = 2 => not divisible
12 modulo 3 = 0 => divisible
13 modulo 3 = 1 => not divisible
14 modulo 3 = 2 => not divisible
15 modulo 3 = 0 => divisible
Hints:

If we look at the explanation, a simple algorithm comes to mind:
Start by iterating from 1 and check if it is divisible by B.
Keep a counter of how many numbers you printed so far.
Stop when you reached the A number of printed numbers.
STEP 1 OF 7
    Ctrl + Enter to check

    SCALA · WHILE LOOPS & FOR LOOPS

    Print Multiples in Scala, explained

    Problem overview

    The method printMultiples(A: Int, B: Int): Unit receives two positive integers. It prints the first A positive numbers that are divisible by B, one per line. It returns nothing: the result is the console output.

    A number X is divisible by B when X % B == 0, that is, when dividing leaves no remainder. In the example, A = 5 and B = 3. The multiples of 3 are 3, 6, 9, 12, 15 and so on, and the first five of them are printed:

    3
    6
    9
    12
    15
    

    Approach: scan upward and count what you print

    You don't know in advance how far you must go to find A multiples, so there is no natural range to loop over. The simple method is to try the numbers 1, 2, 3, ... in order, test each one with %, and print the ones that pass. A second counter records how many have been printed, and the loop stops when that counter reaches A.

    This uses two separate variables for two separate jobs. One is the number being tested, and it goes up on every pass. The other is the number of multiples found so far, and it goes up only when a multiple is printed. A while loop suits this, because the stopping rule depends on the count and not on a fixed number of passes.

    There is a shortcut: the multiples of B are B, 2 * B, 3 * B, and so on, so a loop over 1 to A printing i * B does the same job. This lesson practises the scan-and-count pattern, which also works when the test is more complicated than divisibility.

    Step by step

    1. Declare the number being tested. var currentNumber = 1 starts the scan at the first positive integer. It is a var because it changes on every pass.
    2. Declare the count. var printedSoFar = 0 starts at zero because nothing has been printed yet.
    3. Loop until enough are printed. The condition printedSoFar < A keeps the loop going while fewer than A multiples have been printed. When the count reaches A, the condition is false and the loop stops.
    4. Test for divisibility. Inside the loop, an if checks currentNumber % B == 0.
    5. Print the multiple with println(currentNumber) inside the if.
    6. Count it. Still inside the if, add 1 to printedSoFar with += 1. Scala has no ++ operator.
    7. Move to the next number. After the if, but still inside the loop, add 1 to currentNumber. This line must run on every pass, whether or not the number was a multiple. If it sat inside the if, the first number that wasn't a multiple would be tested again and again, and the loop would never end.

    For A = 5 and B = 3, the numbers 1 and 2 fail the test, 3 passes and is printed, 4 and 5 fail, 6 passes, and so on. The count reaches 5 when 15 is printed, and the loop ends there. currentNumber is then 16, but nothing is printed for it.

    The solution in Scala

    class Solution {
        def printMultiples(A: Int, B: Int): Unit = {
            var currentNumber = 1
            var printedSoFar = 0
            while (printedSoFar < A) {
                if (currentNumber % B == 0) {
                    println(currentNumber)
                    printedSoFar += 1
                }
                currentNumber += 1
            }
        }
    }
    

    The Scala details worth a closer look:

    • Unit as the return type. Unit is Scala's "nothing useful" type, like void in other languages. The method's work is the printing, so it returns nothing.
    • var and val. Both counters change, so they are var. A val can't be reassigned, and += on it is a compile error.
    • The parameters are values. A and B can't be reassigned inside the method, which is why the code counts upward with its own variable instead of reducing A.
    • % is the remainder. On non-negative Int values, 6 % 3 is 0 and 7 % 3 is 1.
    • Newlines. println ends each output with a line break, which gives one number per line.

    Complexity

    Time: O(A * B). The last multiple printed is A * B, and the scan visits every number from 1 up to it, doing a constant amount of work for each. Looping over 1 to A and printing i * B would take O(A).

    Space: O(1). The method keeps two integers however large A and B are.

    Edge cases and common mistakes

    • B = 1. Every number is a multiple, so printMultiples(3, 1) prints 1, 2 and 3.
    • B larger than A. This changes nothing: printMultiples(2, 10) prints 10 and 20.
    • Counting every pass. If printedSoFar were increased outside the if, the loop would stop after A numbers were tested, not A multiples were printed.
    • Stopping at A instead of counting. A condition such as currentNumber <= A would test the numbers up to A and print only those that happen to be multiples.
    • Starting at 0. Zero is divisible by every B and would be printed first, which gives a different output from the example.
    • Overflow. Int is 32 bits, so a product A * B above 2,147,483,647 would make currentNumber wrap to a negative value. The lesson's inputs are small enough to avoid this.

    Testing

    • A = 5, B = 3 prints 3, 6, 9, 12 and 15.
    • A = 3, B = 1 prints 1, 2 and 3.
    • A = 1, B = 7 prints 7.
    • A = 4, B = 5 prints 5, 10, 15 and 20.
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free