F#无限的阿姆斯特朗号码

时间:2015-10-11 17:33:55

标签: f# stream

我正在尝试在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;;没有任何反应,那么好像程序冻结了。

1 个答案:

答案 0 :(得分:3)

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