我一直在尝试这个问题几个小时,仍然坚持下去。谁能帮忙。寻找建议:
使用列表推导来定义一个函数三元组n ,它返回一个正整数三元组的列表 (x,y,z)都小于或等于 n ,这样 x ^ 2 + y ^ 2 = z ^ 2 < / p>
不要产生重复的三元组或三元组,它们是已经生成的三元组的排列。
答案 0 :(得分:1)
我有一些代码可以解决这个问题......
branchTriple = [
\(a,b,c) -> (a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c),
\(a,b,c) -> (a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c),
\(a,b,c) -> (2*b - a + 2*c, b - 2*a + 2*c, 2*b - 2*a + 3*c)
]
primitiveTriples l = pt (3,4,5) where
pt x = x : concatMap pt (filter l $ map ($ x) branchTriple)
allTriples l = let
pt = primitiveTriples l
mtriple (a,b,c) n = (a*n, b*n, c*n)
multiples p = takeWhile l $ map (mtriple p) [1..]
in concatMap multiples pt
usage n = allTriples (\(a,b,c) -> all (<= n) [a,b,c])
此代码使用Tree of primitive Pythagorean triplets。我将重新格式化以使用列表推导作为读者的练习。
答案 1 :(得分:0)
您可以使用以下代码:
isSquare x = x == head (dropWhile (< x) squares)
where squares = scanl1 (+) [1,3..]
然后定义:
triples n = take n [(i,j,truncate (sqrt (fromIntegral (i*i+j*j) :: Double))) | i <- [1 ..], j <- [1 ..i-1], isSquare(i*i+j*j)]
在这种情况下,第一个元素总是大于第二个元素。
如果您还想要订购元组的元素,请尝试:
triples n = take n [(j,i,truncate (sqrt (fromIntegral (i*i+j*j) :: Double))) | i <- [1..], j <- [1..i-1], isSquare(i*i+j*j)]
使用第一种方法测试数字是否为正方形是非常低效的,您可以将其替换为:
isSquare x = let x' = truncate $ sqrt (fromIntegral x :: Double) in x'*x' == x
答案 2 :(得分:0)
这是否符合要求?
ghci> [(x,y,z) | z<-[1..], x<-[1..z], y<-[1..z], x^2+y^2==z^2, x<y ]
[(3,4,5),(6,8,10),(5,12,13),(9,12,15),(8,15,17),(12,16,20),
(7,24,25),(15,20,25),(10,24,26),(20,21,29),(18,24,30),(16,30,34),
(21,28,35),(12,35,37),(15,36,39),(24,32,40),(9,40,41),
....^Cinterrupted