Start learning free

LESSON 140 OF 348 · LOOPS & GLOBAL VARIABLES

Student Grades in Kotlin: Averaging an IntArray with a for Loop

Practice Read the full explanation

Given the grades of a student as an array, determine if the student has passed the class.

A Student has passed the class if the average of grades is 5 or more.

The average is defined as (grades[0] + grades[1] + ... + grades[n - 1]) / n

Example 1:

Input: grades = [4, 7, 5, 9, 8, 2]
Output: true
Explanation:
average = (4 + 7 + 5 + 9 + 8 + 2) / 6 =
= 35 / 6 = 5.833333333... >= 5

Example 2:

Input: grades = [4, 7, 5, 3, 8, 2]
Output: false
Explanation:
average = (4 + 7 + 5 + 3 + 8 + 2) / 6 =
= 29 / 6 = 4.83333.. < 5

Hints:

The problem can be broken in 3 steps:
1. Compute the sum of the array
2. Compute the average by dividing the sum by the length of the array
3. Decide the result based on the average being greater than or equal to 5
Let's start with step 1: How can we compute the sum of the array?

First of all, we should store this sum somewhere as we compute it. That 'somewhere' is a variable, let's name it sum. We have to iterate through every element of grades and add its value to sum. How can we achieve this?

With a loop! Let's use a for loop and a variable grade to iterate through the elements:
sum = 0
for each grade in grades:
	sum += grade
When the loop terminates, we know the sum. What should we do next?

We should compute average = sum / length and return average >= 5:
sum = 0
for each grade in grades:
	sum += grade
average = sum / length
return average >= 5


We have a for loop that performs exactly n iterations (n is the length of grades), thus the Time Complexity is O(n).
The only extra space we use are the variables sum, average and the iterator variable grade inside the loop, thus the Extra Space used is O(1).
STEP 1 OF 5
    Ctrl + Enter to check

    KOTLIN · LOOPS & GLOBAL VARIABLES

    Student Grades in Kotlin, explained

    Problem overview

    The function hasPassed receives an IntArray named grades and returns a Boolean. A student passes when the average of the grades is 5 or more. The average is the sum of the grades divided by how many there are.

    In the first example, [4, 7, 5, 9, 8, 2] sums to 35 across 6 grades, so the average is about 5.83 and the answer is true. In the second, [4, 7, 5, 3, 8, 2] sums to 29, the average is about 4.83, and the answer is false.

    Approach: sum, divide, compare

    The task breaks into three small pieces. First, add up every grade. Second, divide the sum by the number of grades. Third, compare the average with the passing mark of 5 and return the result of that comparison.

    Adding up an array needs a loop with a variable that remembers the total so far. The loop visits each grade exactly once, so the time is linear in the number of grades. Only a few variables are stored, so the extra space stays constant.

    Step by step

    1. Declare the running sum as var sum = 0f. It is a var because it changes on every pass, and the f suffix makes it a Float rather than an Int, so that the later division keeps its fractional part.
    2. Loop over the grades with for (grade in grades). The loop gives you each element in turn, and you don't need an index.
    3. Add each grade to the sum with sum += grade. Adding an Int to a Float gives a Float, and the assignment keeps sum a Float, so no conversion is needed.
    4. Compute the average with val average = sum / grades.size. A val is enough because the average is assigned once. grades.size is the number of elements of an array.
    5. Return the comparison average >= 5. The expression is already a Boolean, so there is no need for if and two returns.

    The solution in Kotlin

    class Solution {
        fun hasPassed(grades: IntArray): Boolean {
            var sum = 0f
            for (grade in grades) {
                sum += grade
            }
            val average = sum / grades.size
            return average >= 5
        }
    }
    

    The Kotlin details behind it:

    • Mixed arithmetic. Kotlin has no implicit conversion between number types in assignments, but arithmetic operators are overloaded for the mixed cases. Float / Int divides as floating point and returns a Float. The comparison average >= 5 also accepts the Int literal 5 next to a Float.
    • Integer division truncates. With an Int sum, 35 / 6 is 5, not 5.83. Here that happens not to change the answer, because for non-negative numbers, rounding down never moves a value across the whole number 5. Still, a Float average matches the definition in the statement, and it is the habit that keeps other averaging problems right.
    • Float has limited precision. It is a 32-bit type, and 35f / 6 prints as 5.8333335. For grades this does not matter. For very large sums, or when you need more digits, use Double, whose literal has no suffix: 0.0.
    • An empty array. The sum is 0f and grades.size is 0, so the division gives NaN (not a number) instead of an exception, as it does for integers. Every comparison with NaN is false, so hasPassed returns false for intArrayOf().
    • Int division by zero throws. If you had used an Int sum and divided by grades.size of 0, Kotlin would throw an ArithmeticException.

    Complexity

    Let n be the length of grades.

    Time: O(n). The loop runs n times and does one addition per pass. The division and the comparison happen once.

    Space: O(1). The function stores sum, average and the loop variable grade, and none of them grows with n.

    Edge cases and common mistakes

    • Exactly 5. The pass mark includes 5, so intArrayOf(5) and intArrayOf(4, 6) both return true. Using > instead of >= would fail them.
    • Just below 5. intArrayOf(4, 5) averages 4.5 and returns false.
    • Dividing by the wrong number. Use grades.size, not the largest index grades.size - 1.
    • Declaring the sum inside the loop. A new variable on every pass forgets the earlier grades.
    • Using val for the sum. A val can't be reassigned, so sum += grade does not compile.
    • Writing 0 instead of 0f. var sum = 0 makes sum an Int, and then sum += grade with a Float would not compile. Starting from 0f keeps the whole computation in floating point.

    Testing

    • intArrayOf(4, 7, 5, 9, 8, 2) gives true.
    • intArrayOf(4, 7, 5, 3, 8, 2) gives false.
    • intArrayOf(5) gives true.
    • intArrayOf(4, 6) gives true.
    • intArrayOf(4, 5) gives false.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free