I was sitting idle after long intensive hours of development (mostly react native with hooks). After completing the task my mind was wanting some easy problems to solve. I don’t know why it happens to me. So, I decided to open HackerRank and picked up the first problem that popped up in the practice ground. The problem was pretty easy to solve but eh… I wanted to do it anyways. So I did it but not just simple scripting, I picked a new language to start with. That way I would allow myself to pick some other language as well. I picked Kotlin. The superset of JAVA 😉
The Problem
The problem is pretty easy. It is about rounding the number to the nearest multiple of five based on some condition. You can click on the below link to open it:
Go ahead and read the question and keep it open in the next tab. Because we are going to take this problem and solve it in a Test Driven Development way. If you are not sure what TDD is then please read the below article:
- Mindset Behind Test-Driven Development (TDD)
- Linked List Implementation in Test Driven Development Way
Okay… so moving ahead with the problem.
The very first thing that I do is Understand the Given Problem Thoroughly (:D). So, to summarize our requirement, below are the use cases that we have to fulfil:
- Find the next multiple of five from the given grade. (e.g.
Grade=78,
NextMultipleOfFive will be 80
) - Round the grade to the nearest multiple of five if the distance between them is less than 3. (e.g.
if 80-78 < 3 then round the number
) - Do not round the grade if the student scores below 38 (e.g.
if grade < 38 then do not round
)
Cool… so that is pretty much the use-case with this problem. So, lets delve into the development with Test Driven Development and Kotlin.
Test-Driven Development With Kotlin
Idea Intellij is my first choice when it comes to writing code. So, if you are using some other IDE, I would recommend you to switch to Idea Intellij because that’s more Intuitive (I wanted to say sexy (:p)).
I have already done the setup on my machine. Below is the project structure that I’m using.
All the application code will reside inside src/main/java
and all the test cases regarding the code will stay in src/test/java
.
The wonderful thing about test cases is that they are self-explanatory or in other words, the test cases are the documented way of coding your way into the application. You always know what a piece of code does. Because you have a proving test case for it.
Below are all the test cases that I wrote for solving this problem. Please take a look, the test cases are self-explanatory. Thanks to the DML features of Kotlin, I can write pure English or Hinglish in the method names of the test cases.
You can write anything in between ‘“’ and that will be considered as a method name in Kotlin.
import org.junit.Assert
import org.junit.Test
class GradingStudentTest {
private val gradingStudent = GradingStudent()
/**
* The logic is pretty simple. Start counting from the given number
* and see if the number is divisible by 5. Return the number of steps
* required to reach the next divisible of five.
*
* By implementing it this way, I have managed to remove a calculation of finding
* the difference between the number and next multiple.
*
* I'm sure there are more ways of implementing the logic and I would encourage
* you to do that.
*/
@Test
fun `it should find the distance of the grade from the next multiple of five`() {
val grade:Int = 73
val distance:Int = gradingStudent.findDistanceFromNextMultipleOfFive(grade)
Assert.assertEquals(2, distance)
val grade2:Int = 75
val distance2:Int = gradingStudent.findDistanceFromNextMultipleOfFive(grade2)
Assert.assertEquals(0, distance2)
}
/**
* This test case verifies the rounding condition of grade.
*/
@Test
fun `it should round the student grade to the nearest multiple of five`() {
val grade = 73
val distance = 2
val roundedVal = gradingStudent.roundGrade(grade, distance)
Assert.assertEquals(75, roundedVal)
}
/**
* This test cases verifies whether the student has scored less marks then required.
*/
@Test
fun `it should not round the grade if the grade is less than 38`() {
val grade = 33
val distance = 2
val unmodifiedGrade = gradingStudent.roundGrade(grade, distance)
Assert.assertEquals(33, unmodifiedGrade)
}
/**
* This test cases verifies the entire working of the problem
* by imitating it with the real problem
*/
@Test
fun `it should return array of rounded grades for input grades respectively`() {
val inputGrades: Array<Int> = arrayOf(73, 67, 38, 33)
val outputGrades: Array<Int> = gradingStudent.calculateGrades(inputGrades)
Assert.assertEquals(4, outputGrades.size)
Assert.assertEquals(75, outputGrades[0])
Assert.assertEquals(40, outputGrades[2])
}
}
I hope you got the test cases and how it works. The Kotlin language is really expressive. You can actually write code that talks to the reader.
Okay… so moving on. Below is the actual code that solves the problem.
class GradingStudent {
fun findDistanceFromNextMultipleOfFive(grade: Int): Int {
var num = grade
var distance:Int = 0
while (num++ % 5 != 0) {
distance++
}
return distance
}
fun roundGrade(grade: Int, distance: Int): Int {
if (grade < 38)
return grade
if (distance < 3)
return grade + distance
return grade
}
fun calculateGrades(inputGrades: Array<Int>): Array<Int> {
val outputGrades:IntArray = IntArray(inputGrades.size)
inputGrades.forEachIndexed { index, grade ->
outputGrades[index] = roundGrade(grade, findDistanceFromNextMultipleOfFive(grade))
}
return outputGrades.toTypedArray()
}
}
Done.
Please let me know if there is something that you want me to shed more light into. And I strongly recommend you to read about Test-Driven Development. It has become an industry standard. Find the links below:
- Mindset Behind Test-Driven Development (TDD)
- Linked List Implementation in Test Driven Development Way
Do comment below if you need clarification with any part of the code.
Leave a Reply