Problem overview
The function parity takes a non-negative integer n and returns the text "even" if n is divisible by 2 and "odd" otherwise. For n = 12 the answer is "even", because 12 divided by 2 leaves no remainder. For n = 13 it is "odd".
Approach
Every integer leaves a remainder of either 0 or 1 when divided by 2. Even numbers leave 0 and odd numbers leave 1. The whole task is therefore to compute that remainder and branch on it. There is no loop and no need to look at the digits.
Divisibility is a question about the remainder, and the remainder operator % answers it. 12 % 2 is 0 and 13 % 2 is 1. So the test is one comparison, n % 2 == 0, and an if/else turns its result into one of two strings. Zero counts as even, since 0 % 2 is 0.
It is better to test for the remainder 0 than for the remainder 1. For non-negative input both work, but the remainder in Rust takes the sign of the left operand, so -3 % 2 is -1, and a check such as n % 2 == 1 would call -3 even. The check against 0 is correct for negative numbers too.
Step by step
- Write the
if. The condition isn % 2 == 0. No parentheses are needed around a condition in Rust, but the braces around the body are required. - Return
"even"from the body. The function's return type isString, an owned, growable text type. A literal such as"even"has the type&str, a borrowed view of text stored in the program, so it has to be converted..to_string()builds a newStringfrom it.String::from("even")does the same. - Add the
else. It runs when the number is not divisible by 2 and returns"odd".to_string(), converted the same way.
The solution in Rust
impl Solution {
fn parity(n: i32) -> String {
if n % 2 == 0 {
return "even".to_string();
} else {
return "odd".to_string();
}
}
}
Some Rust details here:
- Why the conversion is needed. Returning the bare literal
"even"from a function declared-> Stringis a type error, because Rust does not convert between&strandStringautomatically. - The
elseis redundant. Both branches return, so theelsecould be dropped and the secondreturnplaced after theif. The lesson's version keeps it, which makes the two cases easy to see. - An expression form. An
if/elseis an expression in Rust, so the body could also beif n % 2 == 0 { "even".to_string() } else { "odd".to_string() }, with noreturnand no semicolon. - Comparison with
=.n % 2 == 0uses two equals signs, which compare. A single=would assign and does not compile in a condition.
Complexity
Time is O(1): one remainder, one comparison and one string creation, whatever the size of n. Space is O(1) as well, because the returned string has at most four characters.
A worked run
For n = 12, the expression 12 % 2 gives 0, the comparison is true, and the function returns "even" from the first branch. For n = 13, 13 % 2 gives 1, the comparison is false, the first branch is skipped, and the else returns "odd". Exactly one of the two return statements runs on every call.
Edge cases and common mistakes
- Zero.
parity(0)returns"even". - Testing for 1. Checking
n % 2 == 1first works for non-negative input but fails for negative numbers, as shown above. - Wrong case or spelling. The tests compare the exact text, so
"Even"or"evens"fails. - Forgetting the conversion. Leaving out
.to_string()gives a mismatched-types error: the compiler expects aStringand finds a&str. - A semicolon on the last expression. If you use the expression form,
if ... { "even".to_string() } else { "odd".to_string() };with a trailing semicolon would return nothing, and the compiler would complain.
Testing
n = 12gives"even".n = 13gives"odd".n = 0gives"even".n = 1gives"odd".
