我想使用功能方式对此进行计数,我想有效地计算它们,所以我不想存储序列,只需通过它并计算数字
let conjv2 x =
let next n = match n%2 with
|0 -> n/2
|_ -> n*3+1
Seq.initInfinite next
|> Seq.takeWhile(fun n -> n > 1)
|> Seq.length
这不起作用并返回任何正数的0,这是3n + 1猜想,我发现很难有效地计算它们,这段代码工作正常,但我想以功能的方式做到:
let conj x =
let mutable ansa = x
let mutable cycles = 1
while ansa > 1 do
cycles <- cycles+1
ansa <- match ansa%2 with
|0 -> ansa/2
|_ -> ansa*3+1
cycles
答案 0 :(得分:3)
示例的关键问题是您使用的是Seq.initInfinite
而不是Seq.unfold
。
Seq.initInfinite
调用指定的函数,并将元素的索引作为参数(0,1,2,..)Seq.unfold
使用上一次迭代生成的状态调用指定的函数请注意,您的代码也不使用参数x
,因此您的函数最终为'a -> int
而不是int -> int
,这是您所期望的 - 这是一个很好的指示有什么不对劲的!
要解决此问题,请尝试以下方法:
let conjv2 x =
let next n = match n%2 with
|0 -> n/2
|_ -> n*3+1
Seq.unfold (fun st -> let n = next st in Some(n, n)) x
|> Seq.takeWhile(fun n -> n > 1)
|> Seq.map (fun v -> printfn "%A" v; v)
|> Seq.length
传递给unfold
的函数需要返回一个新状态&amp;要发出的值。为了生成无限序列,我们总是返回Some
,并且发出的值是中间状态。
这会返回比原始conj
小2的值,因为conj
以1(而不是0)开头,并且它还计算最后一个值(在此处,我们在{{{}之前停止1}})。因此,您需要在结果中添加2。