我希望通过粘贴并运行“runghc euler4.hs 1000”来实现这一点。由于我很难学习Haskell,有人可以告诉我如何在这里改进吗?特别是那些“来自整体”的人都是一团糟。
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
答案 0 :(得分: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
的{{1}}表达式,修复了/
突出显示的一些样式问题。)
答案 1 :(得分:0)
好的,有几件事:
首先,传递这个问题的下限和上限可能会更好,它会使它更具扩展性。
如果您只使用CL中的前两个(前一个案例中的一个)参数,我们可以轻松处理这种模式匹配并避免像(args !! 0)
这样的令人讨厌的语句:
(arg0:arg1:_) <- getArgs
让我们将这些转换为Int
s:
let [a, b] = map (\x -> read x :: Int) [arg0,arg1]
现在我们可以引用a
和b
,我们的上限和下限。
接下来,让我们创建一个函数,遍历上限和下限之间的所有数字,并获取其产品列表:
products a b = [x*y | x <- [a..b], y <- [x..b]]
我们不必将每个号码重复两次,因此我们在当前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)