Как создать нерекурсивный расчет факториала с использованием итераторов и диапазонов? - PullRequest
0 голосов
/ 24 марта 2020

Я натолкнулся на упражнение Rustlings, которое продолжает меня беспокоить:

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.
}

Намек на решение говорит мне ...

На императивном языке вы можете написать для l oop для перебора умножения значений в переменную. Или вы можете написать код более функционально с помощью рекурсии и предложения соответствия. Но вы также можете использовать диапазоны и итераторы, чтобы решить эту проблему в ржавчине.

Я пробовал этот подход, но мне чего-то не хватает:

if num > 1 {
    (2..=num).map(|n| n * ( n - 1 ) ??? ).???
} else {
    1
}

Должен ли я использовать что-то вроде .take_while вместо if?

1 Ответ

2 голосов
/ 24 марта 2020

Факториал определяется как произведение всех чисел от начального числа до 1. Мы используем это определение и Iterator::product:

fn factorial(num: u64) -> u64 {
    (1..=num).product()
}

Если вы посмотрите на реализация из Product для целых чисел, вы увидите, что она использует Iterator::fold под капотом:

impl Product for $a {
    fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
        iter.fold($one, Mul::mul)
    }
}

Вы можете написать это самостоятельно:

fn factorial(num: u64) -> u64 {
    (1..=num).fold(1, |acc, v| acc * v)
}

См. Также:

...