无对称解的Haskell中的勾股三元组

7y4bm7vi  于 2022-11-14  发布在  其他
关注(0)|答案(6)|浏览(157)

我得在Haskell里做毕达哥拉斯三重运算而没有对称解

terna :: Int -> [(Int,Int,Int)]
terna x = [(a,b,c)|a<-[1..x], b<-[1..x], c<-[1..x], (a^2)+(b^2) == (c^2)]

我得到的结果是:

Main> terna 10
[(3,4,5),(4,3,5),(6,8,10),(8,6,10)]

如你所见,我得到对称的解决方案,如:(3,4,5)(4,3,5).我需要摆脱他们,但我不知道怎么做.有人能帮助我吗?

waxmsbnn

waxmsbnn1#

每次有一个副本时,就有一个版本的a大于B,另一个版本的b大于a。因此,如果要确保只得到其中的一个,只需确保a始终等于或小于b,反之亦然。
实现这一点的一种方法是将其作为条件添加到列表解析中。
另一种更有效的方法是将b的生成器更改为b <- [1..a],因此它仅生成小于或等于ab的值。
说到效率:根本不需要迭代c,一旦得到ab的值,就可以简单地计算(a^2)+(b^2),并检查它是否有自然平方根。

wkyowqbh

wkyowqbh2#

我完全不知道Haskell(也许你现在正在学习它?),但如果你只取a小于或等于b的那些,似乎就可以去掉它们,这样就可以去掉重复的那些。

zvms9eto

zvms9eto3#

尝试使用一个简单的递归生成器:
http://en.wikipedia.org/wiki/Formulas_for_generating_Pythagorean_triples
(new第10条)
http://en.wikipedia.org/wiki/Tree_of_primitive_Pythagorean_triples

编辑(2014年5月7日)

这里,我制作了无限生成器,它可以生成按周长排序的本原三元组(但可以修改为按其他参数排序-斜边、面积...),只要它保持任何三元组都小于根据提供的比较函数从生成器矩阵生成的任何三元组

import Data.List -- for mmult

merge f x [] = x
merge f [] y = y
merge f (x:xs) (y:ys)
               | f x y     =  x : merge f xs     (y:ys) 
               | otherwise =  y : merge f (x:xs) ys 

mmult :: Num a => [[a]] -> [[a]] -> [[a]] 
mmult a b = [ [ sum $ zipWith (*) ar bc | bc <- (transpose b) ] | ar <- a ]

tpgen_matrix = [[[ 1,-2, 2],[ 2 ,-1, 2],[ 2,-2, 3]],
                [[ 1, 2, 2],[ 2 , 1, 2],[ 2, 2, 3]],
                [[-1, 2, 2],[-2 , 1, 2],[-2, 2, 3]]]

matrixsum  =  sum . map sum
tripletsorter x y =  ( matrixsum  x ) < ( matrixsum y ) -- compare perimeter

triplegen_helper b =  foldl1 
            ( merge tripletsorter ) 
            [ h : triplegen_helper h | x <- tpgen_matrix , let h = mmult x b ]

triplets =  x : triplegen_helper x  where x = [[3],[4],[5]]

main =  mapM print $ take 10 triplets
p3rjfoxz

p3rjfoxz4#

您可以执行以下操作:

pythagorean = [ (x,y,m*m+n*n) | 
                                m <- [2..], 
                                n <- [1 .. m-1], 
                                let x = m*m-n*n, 
                                let y = 2*m*n ]
d7v8vwbk

d7v8vwbk5#

以下方法可能有效:从本教程中获得

triangles x = [(a,b,c) | c <- [1..x], b <- [1..c], a <- [1..b] , a^2 + b^2 == c^2]
dwthyt8l

dwthyt8l6#

列表解析语法使这变得很容易:

triplets :: Integer -> [(Integer, Integer, Integer)]
triplets d = [(a,b,c) | a <- [1..d], b <- [a..d], c <- [b..d], a^2 + b^2 == c^2]

这基本上就是说,我们从a s,b s和c s构建一个列表,其中a1更改为db从当前的a更改为d,依此类推。它还说,a^2 + b^2 == c^2应该保持不变。

相关问题