diff --git a/dev/Cargo.toml b/dev/Cargo.toml index 4f725b704b..f6191ea244 100644 --- a/dev/Cargo.toml +++ b/dev/Cargo.toml @@ -116,6 +116,8 @@ bin = [ { name = "generics1_sol", path = "../solutions/14_generics/generics1.rs" }, { name = "generics2", path = "../exercises/14_generics/generics2.rs" }, { name = "generics2_sol", path = "../solutions/14_generics/generics2.rs" }, + { name = "generics3", path = "../exercises/14_generics/generics3.rs" }, + { name = "generics3_sol", path = "../solutions/14_generics/generics3.rs" }, { name = "traits1", path = "../exercises/15_traits/traits1.rs" }, { name = "traits1_sol", path = "../solutions/15_traits/traits1.rs" }, { name = "traits2", path = "../exercises/15_traits/traits2.rs" }, diff --git a/exercises/14_generics/generics3.rs b/exercises/14_generics/generics3.rs new file mode 100644 index 0000000000..f7f5e2ceee --- /dev/null +++ b/exercises/14_generics/generics3.rs @@ -0,0 +1,27 @@ +//fn avg(???) -> ??? +// TODO: write a fuction that takes in a slice of number-like primitives, eg u8, i16, usize +// and returns the mean of the slice +// you do not to implement this for floats due to a language limitation + +fn main() { + // You can optionally experiment here. +} + +//you may add `.unwrap()` to the avg fuction calls if needed +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_u8() { + let input: [u8; 5] = [2, 4, 6, 8, 10]; + let ans: u8 = avg(&input); + assert_eq!(ans, 6); + } + + fn test_i32() { + let input: [i32; 5] = [546, 263, 8764, 4198, 7654]; + let ans: i32 = avg(&input); + assert_eq!(ans, 4285); + } +} diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml index ca3ecf1f03..04621ac139 100644 --- a/rustlings-macros/info.toml +++ b/rustlings-macros/info.toml @@ -736,6 +736,20 @@ hint = """ Related section in The Book: https://doc.rust-lang.org/book/ch10-01-syntax.html#in-method-definitions""" +[[exercises]] +name = "generics3" +dir = "14_generics" +hint = """ +The fuction should have the required traits for the division, +eg Div to divide the total and size of slice, Sum to sum over the slice +and TryFrom as `as T` is disallowed in generic contexs + +You may find the following links usefull: +https://doc.rust-lang.org/std/ops/trait.Div.html +https://doc.rust-lang.org/std/iter/trait.Sum.html +https://doc.rust-lang.org/std/convert/trait.TryFrom.html +""" + # TRAITS [[exercises]] diff --git a/solutions/14_generics/generics3.rs b/solutions/14_generics/generics3.rs new file mode 100644 index 0000000000..b83eb9b2c5 --- /dev/null +++ b/solutions/14_generics/generics3.rs @@ -0,0 +1,37 @@ +use std::iter::Sum; +use std::ops::Div; +use std::convert::TryFrom; + +//use Div as we need to div sum by size of slice &[T] +//Use Sum so that .sum() can be used +//Use Copy as .copied() requires it +//use TryFrom to use T::try_from as `as T` is not allowed + +fn avg(input: &[T]) -> Result +where + T: Div + Sum + TryFrom + Copy, +{ + Ok(input.iter().copied().sum::() / T::try_from(input.len())?) +} +fn main() { + // You can optionally experiment here. +} + +//you may add `.unwrap()` to the avg fuction calls if needed +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_u8() { + let input: [u8; 5] = [2, 4, 6, 8, 10]; + let ans: u8 = avg(&input).unwrap(); + assert_eq!(ans, 6); + } + + fn test_i32() { + let input: [i32; 5] = [546, 263, 8764, 4198, 7654]; + let ans: i32 = avg(&input).unwrap(); + assert_eq!(ans, 4285); + } +}