2

「runghc euler4.hs 1000」を貼り付けて実行するだけでこれが機能することを願っています。私は Haskell を学ぶのに苦労しているので、ここで改善できる方法を誰か教えてもらえますか? 特に、これらすべての「fromIntegral」は混乱しています。

module Main where
import System.Environment

main :: IO ()
main = do 
    args <- getArgs
    let 
        hBound = read (args !! 0)::Int
        squarePal = pal hBound
        lBound = floor $ fromIntegral squarePal / 
                   (fromIntegral hBound / fromIntegral squarePal)
        euler = maximum $ takeWhile (>squarePal) [ x | y <- [lBound..hBound], 
                                                       z <- [y..hBound],
                                                       let x = y * z,
                                                       let s = show x,
                                                       s == reverse s ]
    putStrLn $ show euler

pal :: Int -> Int
pal n
    | show pow == reverse (show pow) = n
    | otherwise = pal (n-1)
    where
        pow = n^2
4

2 に答える 2

1

整数除算が必要な場合は、通常の を使用するために、divを前後に変換する代わりに を使用する必要があります。Integral/

module Main where                                                              
import System.Environment                                                      

main :: IO ()                                                                  
main = do                                                                      
    (arg:_) <- getArgs                                                         
    let                                                                        
        hBound = read arg :: Int                                               
        squarePal = pal hBound                                                 
        lBound = squarePal * squarePal `div` hBound                            
        euler = maximum $ takeWhile (>squarePal) [ x | y <- [lBound..hBound],
                                                       z <- [y..hBound],       
                                                       let x = y * z,          
                                                       let s = show x,         
                                                       s == reverse s ]        
    print euler                                                                

pal :: Int -> Int                                                              
pal n                                                                          
    | show pow == reverse (show pow) = n                                       
    | otherwise = pal (n - 1)                                                  
    where                                                                      
        pow = n * n                                                            

lbound( two を使用する式を書き直し、 で/強調表示されたいくつかのスタイルの問題を修正しましたhlint。)

于 2012-08-21T12:17:11.143 に答える
0

さて、いくつかのこと:

まず、この質問に下限と上限を渡す方が良いかもしれません。これにより、もう少し拡張可能になります。

CL の最初の 2 つ (前のケースでは 1 つ) の引数のみを使用する場合は、パターン マッチングで簡単に処理でき、次のような厄介なステートメントを避けることができます(args !! 0)

(arg0:arg1:_) <- getArgs

これらを s に変換しましょうInt:

let [a, b] = map (\x -> read x :: Int) [arg0,arg1]

aこれで、とb、上限と下限を参照できます。次に、上限と下限の間のすべての数値を実行し、それらの積のリストを取得する関数を作成しましょう。

products a b = [x*y | x <- [a..b], y <- [x..b]]

各番号を 2 回繰り返す必要はないのでx、現在の値から始めてy、さまざまな製品をすべて取得します。

ここから、一部のデータセットで非回文を除外するメソッドを作成します。

palindromes xs = filter palindrome xs
  where palindrome x = show x == reverse $ show x

最後に、メイン関数で:

print . maximum . palindromes $ products a b

確認したい場合は、完全なコードを次に示します。

import System.Environment
main = do
  (arg0:arg1:_) <- getArgs
  let [a, b] = map (\x -> read x :: Int) [arg0,arg1]
  print . maximum . palindromes $ products a b

products a b = [x*y | x <- [a..b], y <- [x..b]]

palindromes = filter palindrome
  where palindrome x = (show x) == (reverse $ show x)
于 2012-08-21T19:39:11.710 に答える