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 computeSum(4) that is 0 + 1 + 2 + 3 = 6, so the program should print 6. The code in the editor prints 16 instead:
def computeSum(n: Int): Int = {
var sum = 0
for (i <- 0 until n) {
sum += n
}
return sum
}
// Do not change this code:
def mainFunction(): Unit = {
println(computeSum(4))
}
Your job is to find the mistake and fix the function.
What goes wrong
The wrong output has a clue in it: 16 is 4 + 4 + 4 + 4. The loop runs four times, for i equal to 0, 1, 2 and 3, and each pass adds the same number to sum. That number is n, the function's parameter, which is 4 for the whole call. It never changes from one pass to the next.
Here is the state after each pass for computeSum(4):
| Pass | i | What is added | sum afterwards |
|---|---|---|---|
| 1 | 0 | 4 | 4 |
| 2 | 1 | 4 | 8 |
| 3 | 2 | 4 | 12 |
| 4 | 3 | 4 | 16 |
In general, the loop adds n to the total n times, so the result is always n * n. The loop variable i, which is the number that should be added, is never used.
Fixing it step by step
- Identify what should be added. The sum is of the numbers 0, 1, 2, up to
n - 1. Those are exactly the valuesitakes in0 until n. - Change the update. Replace
sum += nwithsum += i. Now each pass adds the current number instead of the fixed parameter. - Leave the rest alone. The initial value 0, the range and the
return sumare correct, and so ismainFunction.
The fixed code in Scala
def computeSum(n: Int): Int = {
var sum = 0
for (i <- 0 until n) {
sum += i
}
return sum
}
def mainFunction(): Unit = {
println(computeSum(4))
}
Now the passes add 0, 1, 2 and 3. The total goes 0, 1, 3, 6, and the program prints 6.
Some Scala details behind this code:
- Parameter versus loop variable. Inside the body,
nkeeps the value it was called with, anditakes a new value on each pass. Using the wrong one compiles fine, so only the output reveals the mistake. untilstops beforen.0 until nvisits 0 ton - 1, which is the range the task describes. With0 to nthe sum would includenas well, giving 10 forcomputeSum(4).varand+=. The total is avarbecause it changes on every pass, andsum += iis the short form ofsum = sum + i.returnis optional. The last expression of a method is its value, so ending the method with justsumwould work too. The lesson's code usesreturn, and it works the same.
Common mistakes
- Changing the range instead of the update. Switching to
0 to nor1 until ndoesn't fix the problem, because the loop would still addnrepeatedly. - Printing
n * nby hand. It would match the bug, not the task. - Adding
itwice or addingi + 1. The sum then comes out too large. ForcomputeSum(4), addingi + 1gives 10. - Editing
mainFunction. It is marked as code not to change.
Checking your fix
Run the code in the editor above. It should print 6. Other values to try mentally: computeSum(1) is 0, because the only number visited is 0, and computeSum(0) is 0 too, since the loop does not run. computeSum(10) is 45.
