f#无限流的阿姆斯特朗数



我试图在f#中创建一个包含阿姆斯特朗数的无限流。阿姆斯壮数是一个其立方数加起来等于阿姆斯壮数的数。例如,153是阿姆斯特朗数,因为1^3 + 5^3 + 3^3 = 153。到目前为止,我已经创建了几个函数来帮助我这样做。它们是:

type 'a stream = Cons of 'a * (unit -> 'a stream);;
let rec upfrom n = Cons (n, fun() -> upfrom (n+1));;
let rec toIntArray = function
    | 0 -> []
    | n -> n % 10 :: toIntArray (n / 10);;
 
let rec makearmstrong = function
    | [] -> 0
    | y::ys -> (y * y * y) + makearmstrong ys;;
let checkarmstrong n = n = makearmstrong(toIntArray n);;
let rec take n (Cons(x,xsf)) =
   match n with
   | 0 -> []
   | _ -> x :: take (n-1)(xsf());;
let rec filter p (Cons (x, xsf)) =
    if p x then Cons (x, fun() -> filter p (xsf()))
    else filter p (xsf());;

最后:

 let armstrongs = filter (fun n -> checkarmstrong n)(upfrom 1);;

现在,当我执行take 4 armstrongs;;(或任何小于4的数字)时,这完美地工作并给我[1;153;370;371],但如果我执行take 5 armstrongs;;什么也没有发生,似乎程序冻结了。

我认为问题是407之后没有数字是它们的立方之和(参见http://oeis.org/A046197),但是当你的代码评估take 1 (Cons(407, filter checkarmstrong (upfrom 408)))的等量时,它将强制尾部的评估,过滤器将永远递归,永远不会找到匹配的下一个元素。还要注意,您对阿姆斯特朗数的定义与维基百科的定义不同,维基百科指出,数字的幂应该是数字中的位数。

相关内容

  • 没有找到相关文章

最新更新