We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Ground Rules: Values, Types, Control Flow step 15 of 24
loop, while, for, and break with a value
Count how many Collatz transitions a positive starting number takes to reach 1.
pub fn collatz_steps(start: u64) -> u32
While the current number is greater than one, halve it if it is even; otherwise multiply it by three and add one. Count each transition once. The starting value is not itself a step.
| Start | Steps |
|---|---|
| 1 | 0 |
| 6 | 8 |
| 27 | 111 |
Inputs are positive values whose trajectories reach 1, whose intermediate
calculations fit in u64, and whose step counts fit in u32. Zero is outside
this contract: repeatedly halving zero never reaches one. No overflow or
cycle-handling behavior is requested outside the valid-input domain.
For this exercise, use a loop expression and return the count with
break count. A while n != 1 implementation would also express the algorithm
correctly, but would not practice returning a value from a loop. Output tests
check the count, not which loop syntax you used.
Return a value from a loop
break value ends its target loop and supplies the loop expression's result.
This complete example doubles a value until it reaches a threshold:
fn main() {
let mut value = 1u32;
let reached = loop {
if value >= 10 {
break value;
}
value *= 2;
};
assert_eq!(reached, 16);
}
A bare break supplies (), the unit value. The starter uses a bare break
in the function's final loop expression, but the function promises a u32.
That is why it produces E0308, a type mismatch. Supply the count when you
break, and keep the loop as the function's final expression.
If several breaks target the same loop, their values must have compatible
types. A loop with no break targeting it can diverge and has type !.
return exits the containing function rather than supplying a loop result.
Choose the loop that describes the work
looprepeats until control flow inside it exits, and supports a result supplied bybreak.whilechecks a condition before each iteration. This is useful when the continuation test belongs at the top.fortakes items from anIntoIteratorvalue until the iterator returnsNone, unless the body exits earlier.
while and for evaluate to () when they complete normally. A value-bearing
break cannot target either one. A break inside a nested loop can target an
enclosing loop by its label; the target determines whether a value is allowed.
Labeled blocks can also produce values through labeled breaks.
Iterate over values when you need values
When processing a collection, direct iteration avoids maintaining a separate
index. Use enumerate() when you also need the position:
fn main() {
let values = [2i64, 4, 6];
let mut total = 0;
for value in &values {
total += value;
}
assert_eq!(total, 12);
let mut positions = Vec::new();
for (index, value) in values.iter().enumerate() {
positions.push((index, *value));
}
assert_eq!(positions, [(0, 2), (1, 4), (2, 6)]);
}
Clippy's needless_range_loop lint can suggest this change when a range
variable is used only to index a collection. It does not diagnose every
hand-written index loop. Direct iteration makes intent clearer, but it does
not prove the surrounding algorithm is correct. Nor does source-level indexing
imply a runtime bounds check on every access: optimization may remove checks.
Apply the pattern to Collatz
Check for n == 1 before updating or incrementing the count. This makes the
answer for start 1 zero. For other valid states, compute one transition,
increase the count, then repeat.
Use n.is_multiple_of(2) for the even test. On the supported Rust toolchain,
Clippy's manual_is_multiple_of lint flags the equivalent n % 2 == 0
pattern. The method expresses divisibility directly; it is not a promise of
faster machine code.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.