I ran into a Rustlings exercise that keeps bugging me:
pub fn factorial(num: u64) -> u64 {
// Complete this function to return factorial of num
// Do not use:
// - return
// For extra fun don't use:
// - imperative style loops (for, while)
// - additional variables
// For the most fun don't use:
// - recursion
// Execute `rustlings hint iterators4` for hints.
}
A hint to solution tells me...
In an imperative language you might write a for loop to iterate through multiply the values into a mutable variable. Or you might write code more functionally with recursion and a match clause. But you can also use ranges and iterators to solve this in rust.
I tried this approach, but I am missing something:
if num > 1 {
(2..=num).map(|n| n * ( n - 1 ) ??? ).???
} else {
1
}
Do I have to use something like .take_while
instead of if
?
The factorial is defined as the product of all the numbers from a starting number down to 1. We use that definition and Iterator::product
:
fn factorial(num: u64) -> u64 {
(1..=num).product()
}
If you look at the implementation of Product
for the integers, you'll see that it uses Iterator::fold
under the hood:
impl Product for $a { fn product<I: Iterator<Item=Self>>(iter: I) -> Self { iter.fold($one, Mul::mul) } }
You could hard-code this yourself:
fn factorial(num: u64) -> u64 {
(1..=num).fold(1, |acc, v| acc * v)
}
See also:
Although using .product()
or .fold()
is probably the best answer, you can also use .for_each()
.
fn factorial(num: u64) -> u64 {
let mut x = 1;
(1..=num).for_each(|i| x *= i);
x
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With