Start learning free

LESSON 124 OF 348 · WHILE LOOPS & FOR LOOPS

Print Multiples in TypeScript: Counting with a while Loop

Practice Read the full explanation

Given two positive integers A and B, print to the console the first A non-negative 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 = 0 => not divisible
5 modulo 3 = 0 => not divisible
6 modulo 3 = 0 => divisible
7 modulo 3 = 0 => not divisible
8 modulo 3 = 0 => not divisible
9 modulo 3 = 0 => divisible
10 modulo 3 = 0 => not divisible
11 modulo 3 = 0 => not divisible
12 modulo 3 = 0 => divisible
13 modulo 3 = 0 => not divisible
14 modulo 3 = 0 => 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

    TYPESCRIPT · WHILE LOOPS & FOR LOOPS

    Print Multiples in TypeScript, explained

    Problem overview

    The method printMultiples(A, B) receives two positive integers. It must print, one per line, the first A positive numbers that are divisible by B. A number is divisible by B when dividing it by B leaves no remainder, that is, when number % B is 0.

    In the example, A = 5 and B = 3. The method prints 3, 6, 9, 12 and 15. These are the first five multiples of 3, and they are not the numbers up to 5: A says how many numbers to print, not how far to count.

    Approach: two counters, one loop

    We do not know in advance where the fifth multiple of 3 will be. For a multiple of 3 it is 15, but for other values of B it is somewhere else. So a loop that counts up to a fixed limit does not fit. The loop has to run until A numbers have been printed, however far that takes.

    That suggests two variables:

    • one that walks through the candidate numbers 1, 2, 3, and so on;
    • one that counts how many multiples have been printed so far.

    A while loop that runs as long as the second counter is below A then does the job. On each pass it asks whether the current candidate is divisible by B. If it is, the number is printed and the printed counter goes up by one. Either way, the candidate moves on to the next number.

    Another way would be to skip the divisibility test altogether and print B, 2 * B, 3 * B, up to A * B with a for loop. This lesson uses the testing approach, because it practises the remainder operator and a loop whose length depends on a condition rather than a known count.

    Step by step

    1. Declare currentNumber and set it to 1. It is the candidate being checked.
    2. Declare printedSoFar and set it to 0. It counts the numbers printed so far.
    3. Write a while loop that runs while printedSoFar < A. The loop ends right after the A-th number is printed, which is why a strict "less than" is used.
    4. Test divisibility inside the loop with currentNumber % B == 0.
    5. Print the number inside the if with console.log.
    6. Increase printedSoFar in the same if, because a number has just been printed.
    7. Increase currentNumber after the if, still inside the loop, so that it happens on every pass, whether or not the candidate was printed.

    The solution in TypeScript

    class Solution {
        printMultiples(A: number, B: number): void {
            let currentNumber: number = 1;
            let printedSoFar: number = 0;
            while (printedSoFar < A) {
                if (currentNumber % B == 0) {
                    console.log(currentNumber);
                    printedSoFar++;
                }
                currentNumber++;
            }
        }
    }
    

    For A = 5 and B = 3 the candidate runs through 1, 2, 3, 4, and so on. The values 3, 6, 9, 12 and 15 pass the test and are printed. After 15, printedSoFar is 5, the condition 5 < 5 is false, and the loop ends.

    Some TypeScript details:

    • number for everything. TypeScript has a single type for integers and decimals, so A, B and both counters are plain number values. Whole numbers are exact up to 2^53, which is far more than the loop will reach.
    • void return type. The method prints and returns nothing, so it is declared : void.
    • == and ===. Here both sides are numbers, so currentNumber % B == 0 behaves like the strict version. In new code === is the usual habit, because it never converts types.
    • % is the remainder. For positive operands it gives what you expect: 4 % 3 is 1 and 9 % 3 is 0.

    Complexity

    Time: O(A * B). The candidate has to reach A * B, the A-th multiple, and each candidate costs a constant amount of work. Counting by candidates therefore takes A * B passes.

    Space: O(1). Only two counters are stored. The numbers are printed, not collected.

    The alternative loop that prints i * B for i from 1 to A only needs O(A) passes, because it jumps straight from one multiple to the next. Testing every number is simpler to reason about, and it is fast enough for modest inputs.

    Edge cases and common mistakes

    • B = 1. Every number is divisible by 1, so with A = 4 the method prints 1, 2, 3 and 4.
    • B larger than the first multiples. With A = 3 and B = 7 the output is 7, 14 and 21. The loop passes through many candidates without printing.
    • Forgetting to increase currentNumber on every pass. If the increment is placed inside the if, the candidate stops moving as soon as it fails the test, and the loop runs forever.
    • Forgetting to increase printedSoFar. The condition never becomes false, so the method prints multiples without end.
    • Counting candidates instead of printed numbers. A loop like while (currentNumber <= A) prints the multiples of B up to A. For A = 5 and B = 3 it prints only 3.
    • Starting at 0. Zero is divisible by every B, because 0 % 3 is 0. Starting there would print 0 as the first line. The task wants positive multiples, so the start is 1.

    Testing

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