What the code is supposed to do
The function printEvenNumbers(nums: IntArray) should print the even numbers of an array, one per line. The function mainFunction calls it with intArrayOf(2, 1, 0, 4, 3), so the expected output is 2, 0 and 4.
The starting code compiles and runs, but the output is wrong. It prints the word even twice:
class Solution {
fun printEvenNumbers(nums: IntArray) {
for (num in nums) {
if (num % 2 == 1) {
println("even")
}
}
}
// Do not change this code:
fun mainFunction() {
printEvenNumbers(intArrayOf(2, 1, 0, 4, 3))
}
}
The code has two separate bugs, both inside the loop. One is in the condition and the other is in what gets printed.
Bug 1: the condition selects the wrong numbers
The operator % gives the remainder of a division. Dividing by 2 leaves a remainder of 0 for an even number and 1 for an odd number: 4 % 2 is 0 and 3 % 2 is 1. The condition num % 2 == 1 is therefore true for odd numbers.
In the array [2, 1, 0, 4, 3] the odd numbers are 1 and 3, so the body runs twice. That is exactly why the word appears twice. The even numbers 2, 0 and 4 are all skipped.
The fix is to test for a remainder of 0: num % 2 == 0. Note that 0 itself is even, because it divides by 2 with no remainder, so the expected output includes it.
Bug 2: the print shows text, not the value
println("even") prints the characters inside the quotation marks, every time. Text in quotes is a string literal, and it never changes. To print the number, pass the variable without quotes: println(num).
Both bugs hide each other. With only the first fix, the program would print the word even three times (once for each of 2, 0 and 4) and not the numbers. With only the second fix, it would print the odd numbers 1 and 3. You need both changes to get 2, 0 and 4.
Fixing it step by step
- Run the code and compare. The output has two lines instead of three, and they are words instead of numbers. That points to the condition (wrong count) and the print (wrong content).
- Check the condition by hand. Try one even and one odd number:
2 % 2is 0 and1 % 2is 1. The test== 1accepts the odd one, which is the wrong way round. - Change
== 1to== 0. - Change
println("even")toprintln(num). - Leave
mainFunctionalone. The comment says not to change it, and the test setup calls it.
The fixed code in Kotlin
class Solution {
fun printEvenNumbers(nums: IntArray) {
for (num in nums) {
if (num % 2 == 0) {
println(num)
}
}
}
fun mainFunction() {
printEvenNumbers(intArrayOf(2, 1, 0, 4, 3))
}
}
This prints 2, 0 and 4, each on its own line.
Kotlin details worth knowing:
intArrayOf. It builds anIntArray. Kotlin has nonew int[]{...}syntax; that is Java.println(num)prints anIntas its digits. The same function prints strings, so the same name works for both. Only the quotes decide whether you get the text or the value.- The condition must be a
Boolean. Kotlin does not treat 0 or 1 as true or false.num % 2 == 0compares and givestrueorfalse.
Edge cases to keep in mind
- Negative numbers. In Kotlin the remainder takes the sign of the left operand, so
-3 % 2is-1and-4 % 2is0. The test== 0works for negatives. The tempting alternativenum % 2 == 1for "odd" would miss -3, because -1 is not 1. Testing for 0 avoids the problem. - Zero. It is even and gets printed.
- An empty array. Nothing is printed.
Common mistakes
- Fixing only one bug. After the first change the output still looks wrong, so it is tempting to undo it. Fix both and check again.
- Printing
"num"in quotes. That prints the wordnum. - Using
=in the condition. A single equals sign is assignment and does not compile inside anifcondition. - Using
num / 2 == 0. Division, not remainder. It is true only for 0 and 1.