Problem overview
The method hasPassed receives an array of integer grades and returns a Bool: true when the average grade is 5 or more, false otherwise. The average is the sum of the grades divided by how many there are.
For [4, 7, 5, 9, 8, 2] the sum is 35 and the average is 35 / 6, about 5.83, so the answer is true. For [4, 7, 5, 3, 8, 2] the sum is 29 and the average is about 4.83, so the answer is false.
Approach: sum, divide, compare
The problem splits into three parts: add up the grades with a loop, divide by the count, and compare the result with 5. The loop uses a running total, the same pattern as any sum.
The one real decision is the number type. If the sum and the division were done in Int, the division would truncate: 29 / 6 is 4. For non-negative grades the comparison with 5 would still come out the same, but the value would no longer be the average the task defines. Using Double keeps the fractional part, so the code computes the real average and compares that.
Step by step
- Declare the total as a
Double.var sum = 0.0is a variable, since it grows, and the literal0.0makes Swift inferDouble. - Loop over the grades with
for grade in grades. - Add each grade, converted.
sum += Double(grade). Swift never mixes number types implicitly, so theInthas to be converted first. - Compute the average. A constant fits, since it is set once:
let average = sum / Double(grades.count). The count is anInt, so it needs the same conversion. - Return the comparison.
average >= 5is already aBool, so noifis needed.
The solution in Swift
class Solution {
func hasPassed(_ grades: [Int]) -> Bool {
var sum = 0.0
for grade in grades {
sum += Double(grade)
}
let average = sum / Double(grades.count)
return average >= 5
}
}
Swift details worth knowing:
- No implicit conversion. Writing
sum += gradewith aDoublesum and anIntgrade is a compile error: Swift cannot convert a value of typeIntto the expected argument typeDouble. - Integer division truncates.
29 / 6inIntis 4. The solution avoids this by dividing twoDoublevalues. - Literals adapt. In
average >= 5the literal5becomes aDoubleautomatically, because literals take the type their context needs. Only variables and constants with a fixed type need explicit conversion. letfor values set once.averagenever changes after its declaration, soletis the idiomatic choice.
Complexity
Time: O(n), where n is the number of grades. The loop visits each grade once, and the division and comparison are constant work.
Space: O(1). The function keeps sum, average and the loop variable.
Edge cases and common mistakes
- Exactly 5.
[5, 5]has an average of 5.0 and returnstrue, because the comparison is>=. - Empty array. The sum is 0.0 and the count is 0.0, so the division gives
nan(not a number). Every comparison withnanis false, so the function returnsfalsewithout crashing. Integer division by zero, in contrast, would crash. - Dividing as integers. Summing in an
Intand dividing bygrades.countgives 4 for 4.83. The pass or fail answer happens to agree for non-negative grades, but the code stops computing the average the task defines. - Using
>. That fails the "5 or more" rule for an average of exactly 5. - Forgetting the count conversion.
sum / grades.countmixesDoubleandIntand does not compile.
Testing
[4, 7, 5, 9, 8, 2]givestrue.[4, 7, 5, 3, 8, 2]givesfalse.[5, 5]givestrue.[]givesfalse.
