Problem overview
The method printEvenOdd takes a positive integer n and prints one line for each number from 0 up to n - 1. If the number is odd, the line is the word odd. If it is even, the line is the number itself. The method prints to the console and returns nothing, which is why its return type is void.
For n = 6 the numbers are 0, 1, 2, 3, 4 and 5. Zero, 2 and 4 are even, so they appear as numbers. One, 3 and 5 are odd, so each becomes the word odd. The output is:
0
odd
2
odd
4
odd
Notice that n itself is never printed: the range stops one short of it.
Approach: visit every number and make one decision
The task has two parts. First, visit every number in the range, which is a job for a for loop. Second, decide for each number which of two things to print, which is a job for if and else. Every number leads to exactly one print, so the two branches must not overlap and must not leave a gap. An if/else pair gives you both properties for free: the else branch runs precisely when the condition is false.
The only real question is how to test for oddness. A number is odd when dividing it by 2 leaves a remainder of 1. TypeScript's remainder operator % returns that remainder, so i % 2 is 0 for even numbers and 1 for odd ones (for non-negative integers, which is all this lesson uses).
Step by step
- Write the loop header. A loop that starts at 0 and stops before
nuseslet i = 0, the conditioni < n, andi++to move on after each pass. The strict<is what keepsnout of the range. Using<=would print one line too many. - Test for odd inside the loop. The body starts with an
ifwhose condition comparesi % 2with 1. When it is true, the body of theifprints the string"odd"withconsole.log. - Handle the even numbers in the
elsebranch. Any number that failed the odd test is even, so printiitself. Becauseconsole.log(i)receives a number, it prints the digits without quotes.
Order does not matter much here. You could also test for even first and print "odd" in the else branch. The lesson tests for odd first because that matches the order in which the task describes the two cases.
The solution in TypeScript
class Solution {
printEvenOdd(n: number): void {
for (let i = 0; i < n; i++) {
if (i % 2 == 1) {
console.log("odd");
} else {
console.log(i);
}
}
}
}
A few TypeScript details are worth knowing here:
- The annotations are only for the compiler.
n: numberand: voidtell tsc what to expect, and they are erased when the code becomes JavaScript. Nothing checks at run time thatnreally is a number. - There is one numeric type. Whole numbers and decimals are both
number, so the loop variableiis inferred asnumberwithout being annotated. ==versus===. The solution compares with==. When both sides are numbers, it gives the same answer as===, the strict comparison. The strict form is the habit to build, because==converts types when the two sides differ and can surprise you.- A string and a number print alike.
console.log("odd")andconsole.log(7)both show their value without quotes, so the output is a clean column of lines. - Remainders keep the sign of the left side.
-3 % 2is-1, not 1. That cannot matter here because the loop only produces non-negative numbers, but it is the reason a test likei % 2 === 1is only safe for non-negative input. Testingi % 2 === 0for even and treating everything else as odd works for negatives too. /is not integer division.7 / 2is3.5. For this lesson that does not come up, because%alone answers the question.
Edge cases and common mistakes
- Off-by-one on the range. The range runs from 0 to
n - 1. Starting at 1 drops the leading0line, and usingi <= nadds a line forn. - Zero counts as even. Zero divided by 2 leaves remainder 0, so the first line is the number
0, not the wordodd. - Very small input. With
n = 1the loop runs once and prints0. Withn = 0it never runs and prints nothing. - Returning instead of printing. The method has to print each line as it goes. Building one string or an array and returning it is a different task, and the lesson's tests look at what is printed.
- Using
=in the condition. A single=assigns a value instead of comparing, soif (i % 2 = 1)does not compile. - Quotes around
i. Writingconsole.log("i")prints the letterion every even pass instead of the number. - Two separate
ifstatements. Aniffor odd followed by anotheriffor even also works, but it tests twice. Theelsesays it better: whatever was not odd is even.
Testing
n = 6prints0,odd,2,odd,4,odd, one per line.n = 1prints just0.n = 0prints nothing.n = 3prints0,odd,2.