Problem overview
The method minValue receives three Int values, A, B and C, and returns the smallest of them. The lesson forbids built-in helpers such as min, so the comparison has to be written by hand.
With A = 7, B = 4 and C = 9 the answer is 4. With A = 3, B = 8 and C = 3 the answer is 3: the smallest value may appear more than once, and the method returns the value, not a position.
Approach: keep the best value seen so far
There are two natural ways to solve this. The first asks of each number, "is it less than or equal to both of the others?" and returns the first one for which the answer is yes. It works, but every extra number adds more conditions to every check.
The lesson uses the second way, which scales better. Keep one variable, minVal, that holds the smallest value seen so far. Start it at A, since after looking at one number that number is the minimum. Then look at the next number: if it is smaller than minVal, it becomes the new minVal. Repeat for the third. Each new number costs one comparison, and the same pattern handles four numbers or four thousand.
Step by step
- Declare
minValwithvarand start it atA. Scala infers the typeIntfromA, so no annotation is needed. It must be avarbecause it will be reassigned; avalwould make the later assignments a compile error. - Add an
ifthat testsB < minVal. Put spaces around the<. Written asB <minVal, the compiler reads<minValas the start of an XML literal and reports',' or ')' expected, but $XMLSTART$< found, which has nothing to do with what you meant. - Inside it, assign
minVal = B. The test is strictly "less than", so an equal value changes nothing, which is fine because the result would be the same. - Add a second, separate
ifforC < minValand assignminVal = Cin it. It must be a separateif, not anelse:Chas to be compared whether or notBreplaced the minimum. - Return
minVal. After both checks it holds the smallest of the three.
The solution in Scala
class Solution {
def minValue(A: Int, B: Int, C: Int): Int = {
var minVal = A
if (B < minVal) {
minVal = B
}
if (C < minVal) {
minVal = C
}
return minVal
}
}
A few Scala details are worth knowing:
returnis optional. In Scala the last expression of a block is its value, so ending the method with justminValon its own line works the same way, and that is the more common style. The explicitreturnis legal and does the same thing here.- The return type is written after the parameters.
): Int =declares that the method gives back anInt, and the body in braces follows the=. - Parameters are values.
A,BandCcan't be reassigned inside the method, which is why the lesson copiesAinto a separatevar. - Capital parameter names are legal. Scala style usually starts parameter names in lower case, but the lesson's names are
A,BandC, and the method works with them. - An
ifwithoutelseis fine here. Used as a statement, it simply does nothing when its condition is false.
Edge cases and common mistakes
- Ties.
minValue(3, 8, 3)returns 3. With<the second 3 doesn't replace the first, and with<=it would replace it with an identical value, so both comparisons give the correct answer. - All values equal.
minValue(5, 5, 5)returns 5, and no assignment happens at all. - Negative numbers and extremes.
minValue(-1, -7, -3)returns -7, andminValue(Int.MinValue, 0, 3)returns -2147483648. Only comparisons are used, so nothing can overflow. - Starting at 0. Initializing
minValto 0 instead ofAbreaks every case where all three numbers are positive, because nothing is smaller than 0 and the method would return 0. Start from a value that is actually one of the inputs. - Using
else iffor the second check. IfBreplacedminVal, theCcomparison would be skipped. ForminValue(9, 8, 1)that would return 8 instead of 1. - Declaring
minValwithval. The compiler rejects the later assignments with a reassignment-to-val error.
Testing
minValue(7, 4, 9)gives4.minValue(3, 8, 3)gives3.minValue(-1, -7, -3)gives-7.minValue(9, 8, 1)gives1.minValue(5, 5, 5)gives5.
