我正在寻求帮助,主要是因为我对F#环境很新。我需要使用F#stream来生成无限的Armstrong数字流。任何人都可以帮助这个。我做了一些mambo jumbo,但我不知道我要去哪里。
type 'a stream = | Cons of 'a * (unit -> 'a stream)
let rec take n (Cons(x, xsf)) =
if n = 0 then []
else x :: take (n-1) (xsf());;
//to test if two integers are equal
let test x y =
match (x,y) with
| (x,y) when x < y -> false
| (x,y) when x > y -> false
| _ -> true
//to check for armstrong number
let check n =
let mutable m = n
let mutable r = 0
let mutable s = 0
while m <> 0 do
r <- m%10
s <- s+r*r*r
m <- m/10
if (test n s) then true else false
let rec armstrong n =
Cons (n, fun () -> if check (n+1) then armstrong (n+1) else armstrong (n+2))
let pos = armstrong 0
take 5 pos
答案 0 :(得分:3)
说实话,你的代码看起来有点混乱。
我能想到的最基本的版本是:
let isArmstrong (a,b,c) =
a*a*a + b*b*b + c*c*c = (a*100+b*10+c)
let armstrongs =
seq {
for a in [0..9] do
for b in [0..9] do
for c in [0..9] do
if isArmstrong (a,b,c) then yield (a*100+b*10+c)
}
当然假设阿姆斯特朗号是一个3位数字,其中数字的多维数据集之和就是数字本身
这会让你:
> Seq.toList armstrongs;;
val it : int list = [0; 1; 153; 370; 371; 407]
但是应该很容易添加更宽的范围或删除一位数字(想一想)。
这个问题看起来很有趣,我选择实施一般情况(见这里):
let numbers =
let rec create n =
if n = 0 then [(0,[])] else
[
for x in [0..9] do
for (_,xs) in create (n-1) do
yield (n, x::xs)
]
Seq.initInfinite create |> Seq.concat
let toNumber (ds : int list) =
ds |> List.fold (fun s d -> s*10I + bigint d) 0I
let armstrong (m : int, ds : int list) =
ds |> List.map (fun d -> bigint d ** m) |> List.sum
let leadingZero =
function
| 0::_ -> true
| _ -> false
let isArmstrong (m : int, ds : int list) =
if leadingZero ds then false else
let left = armstrong (m, ds)
let right = toNumber ds
left = right
let armstrongs =
numbers
|> Seq.filter isArmstrong
|> Seq.map (snd >> toNumber)
但是这些数字很快变得非常稀疏,使用它很快就会让你失去记忆但是 前20个是:
> Seq.take 20 armstrongs |> Seq.map string |> Seq.toList;;
val it : string list =
["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "153"; "370"; "371";
"407"; "1634"; "8208"; "9474"; "54748"; "92727"; "93084"]
这是最基本的版本 - 如果您只是枚举所有数字并使用基本数学来获取和取幂数字,您可以获得更高的速度/性能;)...确定您可以弄明白