We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Rust: zero to hero step 4 of 342
let, immutability by default, and mut
Return the largest value seen so far at every position in a slice.
pub fn running_max(values: &[i32]) -> Vec<i32>
The output has the same length as the input. At position i, it contains
the maximum of input positions 0 through i, including the current value.
| Input | Output |
|---|---|
[3, 1, 4, 1, 5] |
[3, 3, 4, 4, 5] |
[-1, -9] |
[-1, -1] |
[5, 5, 5] |
[5, 5, 5] |
[] |
[] |
Preserve one output for every input, including duplicates. Values may be
anywhere in the i32 range. The running maximum can stay the same or
increase; it never decreases.
Make a binding mutable when it needs assignment
The starter tries to assign a new value to best, which was declared
without mut:
let best = i32::MIN;
best = 7;
This produces E0384: an initialized immutable binding cannot be assigned
another value. Add mut to permit reassignment:
let mut best = i32::MIN;
best = 7;
let introduces a variable binding. Immutability by default makes intended
mutation visible in the code; it is distinct from the ownership and borrowing
rules that govern access to values.
A new let can also shadow an earlier name, creating a different binding.
Shadowing inside the loop would not update the outer best for the next
iteration, so reassignment is the useful operation here.
The binding's mutability is not a promise that everything reachable through
its value is immutable. For example, an immutable binding can hold a mutable
reference. For this exercise's plain i32, focus on whether best itself
may be assigned a new value.
Use mut where this implementation needs it
In the supplied loop, best changes as larger values arrive, and out
needs mutable access for push. The vector does not need to be reassigned
for its binding to require mut.
Rust's unused_mut lint warns when a binding was marked mutable but does
not need to be. This exercise treats warnings as errors. That does not
impose a fixed number of mutable bindings on every valid solution; it asks
whether each declaration needs mutable access in that implementation.
Read one copied integer at a time
for &v in values {
// Compare v with the running maximum, then append that maximum.
}
values is a borrowed slice. Iterating over it yields references to its
elements. The pattern &v matches each reference and copies the i32 into
v, because i32 implements Copy. The input is left unchanged. The same
pattern cannot move a non-Copy value out of a shared reference.
Choose a starting value that handles negatives
Start best at i32::MIN, the smallest possible input value. Every element
is greater than or equal to it. If the first element equals i32::MIN,
leaving best unchanged is already correct.
Starting at zero would incorrectly report zero for an all-negative prefix. The empty case needs no special output: the loop runs zero times and the initially empty vector is returned.
For each value, update best if needed, then append best to out.
Appending only when a new maximum appears would omit required positions.
Passing requires compilation, correct outputs and Clippy with warnings
treated as errors.
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.