Problem overview
The absolute value of a number is its distance from zero, so it is never negative. The lesson asks you to rebuild this yourself, without calling Swift's built-in abs(). The method is absoluteValue(_ n: Int) -> Int in the class Solution. Negative numbers come back positive, and zero and positive numbers come back unchanged.
For example, -5 gives 5, 250 gives 250 and 0 gives 0.
Approach
Only negative numbers need to change. Flipping the sign of a negative number gives its positive twin: -(-5) is 5. A number that is zero or positive is already its own absolute value. That splits the work into two cases, and a single comparison n < 0 tells them apart.
Step by step
- Test for a negative number. Write
if n < 0 { }. Swift needs no parentheses around the condition, but the braces are required. - Return the negation. Inside the
if,return -n. The unary minus flips the sign, so a negative input becomes positive. - Return the input otherwise. Write
} else {on one line, andreturn nin the else branch. Zero lands here, which is right: the absolute value of 0 is 0.
The solution in Swift
class Solution {
func absoluteValue(_ n: Int) -> Int {
if n < 0 {
return -n
} else {
return n
}
}
}
A few Swift details are worth knowing:
- The underscore. The parameter is declared as
_ n: Int, so callers writeabsoluteValue(-5)with no argument label. Without the underscore, they would have to writeabsoluteValue(n: -5). - Every path returns. Swift requires a function with a return type to return a value on every path. Both the
ifand theelsereturn, so the compiler is satisfied. - The minus sign. In
-n, the minus is the prefix negation operator applied ton. It is not a subtraction, and it works on any signed number type. - An
Intparameter. The method takes whole numbers. Passing a decimal such as-0.14doesn't compile, because aDoubleisn't anInt.
Why the comparison comes first
A common first instinct is to look for a trick, such as multiplying by -1 for every input. That would turn positive numbers negative. The function has to look at the sign before it decides what to do, and that is exactly what a conditional is for. The same pattern, test a condition and return one of two values, appears in many small functions, so this exercise is good practice for it. Each call takes exactly one of the two branches, and the other is skipped entirely.
You can also trace a call by hand. For absoluteValue(-5), the test -5 < 0 is true, so the function returns -(-5), which is 5. For absoluteValue(250), the test 250 < 0 is false, so the function takes the else branch and returns 250.
Using it
let s = Solution()
print(s.absoluteValue(-5))
print(s.absoluteValue(0))
print(s.absoluteValue(250))
This prints:
5
0
250
Edge cases and common mistakes
- Zero. Using
n <= 0would still give the right answer, because-0is0, but it does a pointless negation.n < 0is the cleaner test. - Forgetting the else path. With only the
ifreturning, the compiler reports that the function is missing a return on the other path. - Returning
nunchanged for negative input. That makes the function an identity function that passes only the positive tests. - The smallest
Int.Intis a 64-bit signed integer, and its most negative value,Int.min, has no positive counterpart. Evaluating-nfor it overflows, and Swift stops the program at run time instead of wrapping around silently. Every other value is safe.
