运行时取总小于值



我试图生成一个偶数整数列表,而列表中项目的总和不等于给定的数字。例如,如果阈值k为20,则预期输出为[0;2;4;6;8]

我可以生成一个列表,其中最大值小于阈值,如下所示:

let listOfEvenNumbersSmallerThanTwenty =
Seq.unfold (fun x -> Some(x, x + 1)) 0 // natural numbers
|> Seq.filter (fun x -> x % 2 = 0) // even numbers
|> Seq.takeWhile (fun x -> x <= 20)
|> List.ofSeq

(我知道我可以将展开和过滤器组合到Some(x, x + 2),但这个任务是出于教育目的)

我设法创建了一个不同的列表,运行总数小于阈值:

let runningTotal =
listOfEvenNumbersSmallerThanTwenty 
|> Seq.scan (+) 0
|> Seq.filter (fun x -> x < 20)
|> List.ofSeq

但是为了做到这一点,我在listOfEvenNumbersSmallerThanTwenty中设置了阈值(这比所需的项目要多),并且我已经丢失了初始序列。我也尝试过使用可变值,但我真的不喜欢那个路由。

你可以创建一个小的谓词函数来封装一个可变的和。

let sumLessThan threshold =
let mutable sum = 0
fun x ->
sum <- sum + x
sum < threshold

用法非常简单,它可以应用于任何序列

Seq.initInfinite ((*) 2) |> Seq.takeWhile (sumLessThan 20)

在封装时使用可变状态并没有什么不好(检查Seq模块中可变变量的用法)

我认为这是一个非常优雅的解决方案(尽管不是最有效的):

let evens = Seq.initInfinite (fun i -> 2 * i)
Seq.initInfinite (fun i -> Seq.take i evens)
|> Seq.takeWhile (fun seq ->
Seq.sum seq <= 20)
|> Seq.last
|> List.ofSeq

最新更新