Я пишу функцию Rust, которая принимает список чисел и максимальное значение и суммирует все кратные заданных чисел до максимума (дубликаты учитываются только один раз).Первая версия функции, которую я написал, была
use std::collections::HashSet;
pub fn sum_of_multiples(limit: u32, factors: &[u32]) -> u32 {
let set: HashSet<u32> = factors
.iter()
.map(|factor| {
let top: u32 = (limit - 1) / factor;
(1..=top).map(move |num| num * factor)
}).flatten()
.collect();
set.iter().fold(0, |acc, num| acc + num)
}
(я знаю, слияние HashSets
, как это, вероятно, не лучшее решение).Это дает ожидаемый результат:
println!("{}", sum_of_multiples(100, &[3, 5])) // 2318
Когда я вынимаю вызов на collect
в середине и цепью последнего fold
, я получаю другой ответ:
pub fn sum_of_multiples(limit: u32, factors: &[u32]) -> u32 {
let val: u32 = factors
.iter()
.map(|factor| {
let top: u32 = (limit - 1) / factor;
(1..=top).map(move |num| num * factor)
}).flatten()
.fold(0, |acc, num| acc + num);
val
}
Результат:
println!("{}", sum_of_multiples(100, &[3, 5])) // 2633
Я знаю, что итераторы вычисляются лениво, но я предположил, что они оцениваются последовательно в порядке их использования.Это из-за поведения flatten
с HashSet
s?Я не понимаю, почему результаты отличаются во второй раз, или каково значение (если таковое имеется) 2633 года.