Problem overview
The method hasPassed receives an array of integer grades and returns a Boolean: true if the average grade is 5 or more, false otherwise. The average is the sum of the grades divided by how many there are.
In the first example, the grades 4, 7, 5, 9, 8, 2 add up to 35, and 35 / 6 is about 5.83, so the result is true. In the second, 4, 7, 5, 3, 8, 2 add up to 29, and 29 / 6 is about 4.83, so the result is false.
Approach: sum, divide, compare
The task splits into three small jobs, done in order:
- Add up all the grades with a loop and a running total.
- Divide the total by the number of grades.
- Compare the average with 5 and return the answer.
The loop is the same accumulator pattern as in any running sum: a variable starts at 0, and each grade is added to it. The only new decision is the type of the total, which the next section explains.
Step by step
- Declare
var sum = 0f. Thefsuffix makes the literal aFloat, sosumis aFloat, a 32-bit decimal number. It is avarbecause the loop changes it. Without the suffix,0would make it anInt. - Loop with
for (grade <- grades). The generator takes each element of the array in turn. - Add with
sum += grade. The grade is anIntandsumis aFloat. Scala converts theIntto aFloaton its own, so no cast is needed. - Declare
val average = sum / grades.size. The average never changes after it is computed, so it is aval. AFloatdivided by anIntis aFloat, so the fractional part is kept. The length of an array comes fromsize(lengthis the same). - Return
average >= 5. A comparison is already aBooleanvalue, so it can be returned directly without anif.
The solution in Scala
class Solution {
def hasPassed(grades: Array[Int]): Boolean = {
var sum = 0f
for (grade <- grades) {
sum += grade
}
val average = sum / grades.size
return average >= 5
}
}
Integer division and the Float
Division on two Int values truncates. In Scala, 35 / 6 is 5 and 29 / 6 is 4, with the fraction dropped. With the Float total, 35f / 6 gives 5.8333335, close to the real quotient. For a threshold like 5, both ways happen to agree on the final answer, since a whole-number average of at least 5 exactly matches a total of at least 5 times the count. The Float version is still the better habit, because it holds the real average, which matters as soon as the threshold is not a whole number or you want to print the average.
Other details
average >= 5compares aFloatwith theInt5. Scala widens the 5 to aFloatfirst.- A
Floathas about seven significant digits. For ordinary grades that is plenty, but a total beyond 16,777,216 can lose exactness: adding 1 to 16777216 as aFloatstill gives 16777216.
Complexity
The loop makes one pass over the n grades, so the time is O(n). The method uses only sum, average and the loop variable, so the extra space is O(1).
Edge cases and common mistakes
- Exactly 5. The comparison is
>=, soArray(5, 5)passes with an average of exactly 5. Using>would fail it. - Just below 5.
Array(4, 5)averages 4.5 and returnsfalse. - An empty array. The sum is 0 and
0f / 0isNaN, not a number. Every comparison withNaNis false, so the method returnsfalseand doesn't crash. The statement doesn't promise what to do here. - Dividing before summing. The division belongs after the loop. Dividing inside it gives wrong totals.
- Declaring
suminside the loop. It would reset on every pass.
Testing
Try Array(4, 7, 5, 9, 8, 2), which returns true, and Array(4, 7, 5, 3, 8, 2), which returns false. Add Array(5, 5) (true) and Array(4, 5) (false) to check the boundary.
