We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Ownership I: Moves, Copy, Clone, Drop step 5 of 20
Copy values: translate points and find their centroid
Translate each input point, then append the centroid of the original points.
Make Point Copy so the same point can be passed by value to two helpers.
pub fn centroid_path(points: Vec<Point>, dx: i64, dy: i64) -> Vec<Point>
Output rules
Keep the public Point type and its public x: i64 and y: i64 fields.
Return a vector containing:
- Each input point translated to
(x + dx, y + dy), in input order. - One final point containing the centroid of the original, untranslated points.
Compute each centroid coordinate by summing that coordinate and dividing by
the number of input points. Use integer division, which truncates toward zero:
a total of -3 across two points gives -1, not -2.
For an empty input, return just Point { x: 0, y: 0 }, regardless of the
translation. For one point, return its translated value followed by its
original value. The output always has one more element than the input.
For example, points (1, 2) and (3, 4) with translation (10, 20) produce
(11, 22), (13, 24), then centroid (2, 3).
Assume every translated coordinate and every running coordinate sum fits in
i64, and the input length fits in i64. Keep calculations in integers so
large coordinates remain exact. Overflow behavior is outside this exercise's
input domain.
Why the starter cannot reuse a point
The two supplied helpers take Point by value:
accumulate(total, p)adds a point to the running total.shifted(p, dx, dy)returns a translated point.
Keep these helpers and their signatures. The starter derives Clone but not
Copy. Passing p to accumulate therefore moves it; a later use in shifted
would produce E0382. Deriving Copy as well lets both calls receive a copy
while leaving the local p usable.
Clone alone does not change assignment or argument passing. It provides an explicit method. Copy changes those implicit by-value uses and has Clone as a supertrait, so a Copy type must also implement Clone. Deriving both is the straightforward choice here; handwritten implementations are also possible.
Here is a complete example with a different small value type:
#[derive(Clone, Copy)]
struct Dimensions { width: u32, height: u32 }
fn area(d: Dimensions) -> u64 {
u64::from(d.width) * u64::from(d.height)
}
fn main() {
let size = Dimensions { width: 3, height: 4 };
assert_eq!(area(size), 12);
assert_eq!(size.width, 3);
}
The compile-time assertion
Retain the starter's assert_copy function and its const invocation. The
T: Copy bound requires Point to implement Copy; otherwise compilation fails
with E0277. The const invocation performs no runtime work.
This assertion is in the editable starter. Keeping it is an exercise requirement; the output harness does not independently prevent its removal or prove that your solution uses the supplied helpers.
With the assertion present, the compiler may report the missing Copy bound before the moved-value error. Adding Copy resolves both causes.
When a type can be Copy
A struct can implement Copy only if all its fields are Copy and it has no
Drop implementation. Both Point fields are i64, so it is eligible.
Eligibility alone does not implement the trait.
Adding a String field would make the Copy implementation invalid (E0204). Copying a shared reference, however, is allowed even when the referenced type is not Copy: it duplicates access to the same value, not the value itself. A mutable reference is not Copy, though calls can temporarily reborrow one.
Copy does not guarantee zero work or a particular machine instruction. Large Copy values can be expensive to duplicate. For this small Point, it gives the intended value semantics without an explicit clone or borrow.
Once Point is Copy, use p directly. Calling p.clone() is legal Rust but
triggers Clippy's clone_on_copy lint. Submissions must compile, pass the
output tests and pass 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.