You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-06-24 17:56:45 +02:00
Simplify generic min exercise (#1900)
I was a bit dissatisfied with the test code for the generic min exercise. We were supposed to be testing that the student wrote the generic function correctly, but we only test their `min` function with one type. I rewrote the exercise to test against multiple types, which required that we use the regular `Ord` trait rather than a custom one. I tend to prefer using the real items from `std` when we can because it's a good way to get students familiar with the standard library. I also removed the custom `Citation` type since it wasn't really important to the exercise.
This commit is contained in:
@ -5,12 +5,21 @@ minutes: 10
|
|||||||
# Exercise: Generic `min`
|
# Exercise: Generic `min`
|
||||||
|
|
||||||
In this short exercise, you will implement a generic `min` function that
|
In this short exercise, you will implement a generic `min` function that
|
||||||
determines the minimum of two values, using a `LessThan` trait.
|
determines the minimum of two values, using the [`Ord`] trait.
|
||||||
|
|
||||||
```rust,compile_fail
|
```rust,compile_fail
|
||||||
{{#include exercise.rs:LessThan}}
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
// TODO: implement the `min` function used in `main`.
|
// TODO: implement the `min` function used in `main`.
|
||||||
|
|
||||||
{{#include exercise.rs:main}}
|
{{#include exercise.rs:main}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
- Show students the [`Ord`] trait and [`Ordering`] enum.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
[`Ord`]: https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html
|
||||||
|
[`Ordering`]: https://doc.rust-lang.org/stable/std/cmp/enum.Ordering.html
|
||||||
|
@ -13,46 +13,24 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// ANCHOR: solution
|
// ANCHOR: solution
|
||||||
// ANCHOR: LessThan
|
use std::cmp::Ordering;
|
||||||
trait LessThan {
|
|
||||||
/// Return true if self is less than other.
|
|
||||||
fn less_than(&self, other: &Self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
fn min<T: Ord>(l: T, r: T) -> T {
|
||||||
struct Citation {
|
match l.cmp(&r) {
|
||||||
author: &'static str,
|
Ordering::Less | Ordering::Equal => l,
|
||||||
year: u32,
|
Ordering::Greater => r,
|
||||||
}
|
|
||||||
|
|
||||||
impl LessThan for Citation {
|
|
||||||
fn less_than(&self, other: &Self) -> bool {
|
|
||||||
if self.author < other.author {
|
|
||||||
true
|
|
||||||
} else if self.author > other.author {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
self.year < other.year
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ANCHOR_END: LessThan
|
|
||||||
|
|
||||||
fn min<T: LessThan>(l: T, r: T) -> T {
|
|
||||||
if l.less_than(&r) {
|
|
||||||
l
|
|
||||||
} else {
|
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: main
|
// ANCHOR: main
|
||||||
fn main() {
|
fn main() {
|
||||||
let cit1 = Citation { author: "Shapiro", year: 2011 };
|
assert_eq!(min(0, 10), 0);
|
||||||
let cit2 = Citation { author: "Baumann", year: 2010 };
|
assert_eq!(min(500, 123), 123);
|
||||||
let cit3 = Citation { author: "Baumann", year: 2019 };
|
|
||||||
debug_assert_eq!(min(cit1, cit2), cit2);
|
assert_eq!(min('a', 'z'), 'a');
|
||||||
debug_assert_eq!(min(cit2, cit3), cit2);
|
assert_eq!(min('7', '1'), '1');
|
||||||
debug_assert_eq!(min(cit1, cit3), cit3);
|
|
||||||
|
assert_eq!(min("hello", "goodbye"), "goodbye");
|
||||||
|
assert_eq!(min("bat", "armadillo"), "armadillo");
|
||||||
}
|
}
|
||||||
// ANCHOR_END: main
|
// ANCHOR_END: main
|
||||||
|
Reference in New Issue
Block a user