ここで(HAMMARの提案による)同じリストの代替順序です:
-- the integer points along the diagonals of slope -1 on the cartesian plane,
-- organized by x-intercept
-- diagonals = [ (0,0), (1,0), (0,1), (2,0), (1,1), (0,2), ...
diagonals = [ (n-i, i) | n <- [0..], i <- [0..n] ]
-- the multiples of three paired with the squares
paar = [ (3*x, y^2) | (x,y) <- diagonals ]
とアクションで:
ghci> take 10 diagonals
[(0,0),(1,0),(0,1),(2,0),(1,1),(0,2),(3,0),(2,1),(1,2),(0,3)]
ghci> take 10 paar
[(0,0),(3,0),(0,1),(6,0),(3,1),(0,4),(9,0),(6,1),(3,4),(0,9)]
ghci> elem (9, 9801) paar
True
すべての可能な値を反復処理する斜めのパスを使用することにより、我々は有限時間内に各有限地点に到達することを保証します(ただし、いくつかの点はまだメモリの範囲外です)。
hammarは彼のコメントで指摘しているとおり、 にはまだFalse
の回答を得るのに十分な時間がかかるため、これでは不十分です。
ただし、(3*c,d^2)
の前には(3*a,b^2)
が、 a + b < c + d
の場合は、要素の順序があります。したがって、指定されたペア(x,y)
がpaar
にあるかどうかを確認するには、 のペア(p,q)
とp/3 + sqrt q <= x/3 + sqrt y
のペアをチェックするだけです。
Floating
の数値を使用しないようにするには、少し緩い条件のp <= x || q <= y
を使用します。 確かにp > x && q > y
にはp/3 + sqrt q > x/3 + sqrt y
が含まれていることを示していますので、これには可能な解決策がすべて含まれており、終了することが保証されています。
だから我々はそれを
-- check only a finite number of elements so we can get a False result as well
isElem (p, q) = elem (p,q) $ takeWhile (\(a,b) -> a <= p || b <= q) paar
には、このチェックを構築し、使用することができます。
ghci> isElem (9,9801)
True
ghci> isElem (9,9802)
False
ghci> isElem (10,9801)
False
アドバイス:Haskellのプラットフォームをインストールし、ここで入手可能:http://hackage.haskell.org/platform/ – Tener
'' paar'の意味がどういうかははっきりしていません。このリストはどのように見えますか? elem関数は実際には(答えがTrueの間は)無限リストに作用しますが、リストを生成する方法は問題を引き起こしています。 –