A.
Appendix A: Chapter 1 Exercise Solutions
Written by Massimo Carli
Exercise 1.1
Implement the function sumInRange that sums the values in a List<String> within a given interval. The signature is:
fun sumInRange(input: List<String>, range: IntRange): Int
Exercise 1.1 solution
A possible solution is the following:
fun sumInRange(input: List<String>, range: IntRange): Int = // 1
input
.filter(::isValidNumber) // 2
.map(String::toInt) // 3
.filter { it in range } // 4
.sum() // 5
In this code, you:
- Define the
sumInRangeas requested. - Use
filterwithisValidNumber, which you defined in the chapter. - Invoke
map, passingString::toIntto covert theStringtoInt. - Use
filteragain, passing a lambda that checks whether the value is in the range you pass in as input. - Invoke
sum.
To test the previous code, run:
fun main() {
println(sumInRange(listOf("1", "10", "a", "7", "ad2", "3"), 1..5))
}
Getting:
4
This is the sum of the values in List<String> that are valid Ints and in the range 1..5.
Exercise 1.2
Implement chrono, which accepts a function of type () -> Unit as input and returns the time spent to run it. The signature is:
fun chrono(fn: () -> Unit): Long
Exercise 1.2 solution
A possible implementation for chrono is the following:
fun chrono(fn: () -> Unit): Long { // 1
val start = System.currentTimeMillis() // 2
fn() // 3
return System.currentTimeMillis() - start // 4
}
In this code, you:
- Define
chronoas a function accepting a lambda as an input parameter and returning aLong. - Save the current time in milliseconds in the
startvariable. - Invoke the function
fnyou get as an input parameter. - Return the difference between the current time and the one in
start.
One way to test this is:
fun main() {
val waitOneSec = { Thread.sleep(1000) } // 1
println(chrono(waitOneSec)) // 2
}
Here, you:
- Define the
waitOneSeclambda that waits at least1000milliseconds. - Invoke
chrono, passingwaitOneSecand printing the result.
When you run that code, you get something like:
1005
Note: Even if not strictly related to functional programming, it’s useful to mention why the result isn’t exactly
1000. You might even get a different result every time you run the previousmain. This is due to thesleepfunction of theThreadclass. It asks the current thread to go to theWaitstate for1000milliseconds. After the1000milliseconds, the task may or may not be the next to proceed. You only know that the thread will move from theWaitstate to theRunnablestate. When the thread will actually continue depends on the scheduler responsible for moving a thread from theRunnablestate to theRunningone. This is why you can never get a value less than1000.