毕达哥拉斯三重在哈斯克尔没有对称的解决方案

时间:2011-08-31 18:30:30

标签: haskell functional-programming

我必须在没有对称解决方案的Haskell中完成Pythagorean三重奏。我的尝试是:

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)。我需要摆脱它们,但我不知道如何。任何人都可以帮助我吗?

5 个答案:

答案 0 :(得分:13)

每次复制时,您都有一个版本,其中a大于b,另一个版本的b大于a。因此,如果您想确保只获得其中一个,则只需确保a始终等于或小于b,反之亦然。

实现这一目标的一种方法是将其作为列表理解的条件添加。

另一种更有效的方法是将b的生成器更改为b <- [1..a],因此它只会为b生成小于或等于a的值

说到效率:根本不需要迭代c。获得ab的值后,您只需计算(a^2)+(b^2)并检查其是否具有自然平方根。

答案 1 :(得分:5)

根本不知道Haskell(也许你现在正在学习它?)但是如果你只能拿出a小于或等于的那个,你似乎可以摆脱它们b。这将摆脱重复。

答案 2 :(得分:4)

尝试使用简单的递归生成器:

http://en.wikipedia.org/wiki/Formulas_for_generating_Pythagorean_triples

(新文章)
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

答案 3 :(得分:2)

您可以执行以下操作:

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

答案 4 :(得分:2)

这可能有效:Got it from this tutorial

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