What the code is supposed to do
The function computeSum takes an Int named n and returns the sum of the whole numbers from 0 up to n - 1. For n = 4 that is 0 + 1 + 2 + 3, which is 6. The helper mainFunction prints the result of computeSum(4), so the program should print 6.
The code you start with prints 16:
fun computeSum(n: Int): Int {
var sum = 0
for (i in 0 until n) {
sum += n
}
return sum
}
// Do not change this code:
fun mainFunction() {
println(computeSum(4))
}
What goes wrong
The result 16 is a clue: it equals 4 + 4 + 4 + 4. The loop does run four times, once for each value of i from 0 to 3, so the repetition is right. What is added on each pass is wrong. The line sum += n adds the parameter n, which is 4 during the whole call, instead of the loop variable i, which changes from pass to pass.
Tracing the buggy loop for computeSum(4):
| i | sum before | adds | sum after |
|---|---|---|---|
| 0 | 0 | 4 | 4 |
| 1 | 4 | 4 | 8 |
| 2 | 8 | 4 | 12 |
| 3 | 12 | 4 | 16 |
In general the loop runs n times and adds n each time, so it returns n * n. The task wants the sum of 0 through n - 1, which is a different quantity. For n = 1 the buggy code returns 1, while the correct sum, which is just 0, is different.
Fixing it step by step
- Find what should vary. The sum is meant to collect the different numbers 0, 1, 2 and 3. The only thing in the loop that takes those values is
i. - Replace
nwithiin the addition:sum += i. The loop header, the starting value ofsumand thereturnwere already right. - Check by tracing. The additions are now 0, 1, 2 and 3, so
sumgoes through 0, 1, 3 and 6, and the function returns 6.
The fixed code in Kotlin
fun computeSum(n: Int): Int {
var sum = 0
for (i in 0 until n) {
sum += i
}
return sum
}
fun mainFunction() {
println(computeSum(4))
}
Notes on the Kotlin behind it:
untilexcludes the end.0 until ncovers0ton - 1, which matches the task's sum. The range0..nwould also addn.varfor the total.sumchanges on each pass, so it needsvar. Avalwould not allow+=.- The parameter is a constant during the call. It keeps the value it was called with. Only the loop variable moves, so any code that is meant to react to the loop has to mention it.
Intcan overflow. The return type is a 32-bitInt, which wraps around silently past 2,147,483,647. For very largenthe sum would need aLong.
Checking the fix against a second input
One example can hide a coincidence, so test another. With computeSum(5) the fixed loop adds 0, 1, 2, 3 and 4, and returns 10. The buggy version would return 25, which is 5 times 5. Seeing the wrong and the right answer side by side for more than one input confirms that the change fixed the logic itself, not only the single example that mainFunction prints.
Edge cases and common mistakes
n = 0andn = 1. For 0 the range is empty and the function returns0. For 1 the range holds only 0, so the result is again0.- Negative
n. The range0 until nis empty, so the function returns0. - Using
0..n. It also addsn. Forn = 4that gives10instead of6. - Adding
nafter the loop. Moving the mistake around doesn't help: the sum has to be built fromiinside the loop.
When the output equals one value repeated a number of times, as 16 is 4 four times, look for the loop body using something that never changes.