4

私はハスケルの基礎を学び、プロジェクトのオイラーの簡単なタスクを解決しようとしています:3桁の数字(100.999)の最大の回文を見つけよう。リスト内包表記の奇妙な動作

palindrome = maximum $ filter (\a -> reverse a == a) $ 
            map show [ x*y :: Int | x <- [100 .. 999], 
                  y <- [x, x+1 .. 999]] 

それはまだ間違っている私はx <- [307 .. 999]答えに変更し、間違った答え= 99999を与える:私はこのコードを書いた94249(回文ではなく、最大)とを最終的に私はx <- [308 .. 999],に変更したときに、それ私に正解を与える:906609.

私は本当にこの動作を理解していない:それはいくつかの種類のオーバーフローと切り詰めが生成されたリスト内で発生するようです。誰かが私にこの間違った行動を説明できますか?私はあなたがタスクに答えることを望んでいない:私は私のソリューションは非常に効率的ではない知っている。このコードの動作(リストの切り捨てやメモリの問題)について説明してください。ありがとう。

答えて

9

filterの結果はStringの値のリストなので、maximumはそれらを辞書編集的に比較しています。値を最初にIntに変換する必要があります。型署名は、readが正しい型の値を返すようにします。

palindrome :: Int 
palindrome = maximum . map read . filter ... 

別のアプローチは、フィルタ自体にStringに値を変換することです:

palindrome :: Int 
palindrome = maximum $ filter (\a -> let sa = show a in reverse sa == sa) [ x*y | x <- [100..999], y <- [x..999]] 
+0

素早く答えてくれてありがとう、しかし、辞書式順序は、長さの比較が先行アルファベット順なので、906609です99999より大きい。なぜバインディングを変更した場合にのみ比較結果が変化するのか? – MainstreamDeveloper00

+5

長さはアルファベット順の後に*チェックされます。 '' aaaaaaaaaa "<" b "' – chepner

+0

'x'の下限を変更することで、9つのすべての数字からなる数字が削除されます。 – chepner