[英]What is the Haskell way of solving this?
Haskell的新手。 我有以下代碼
fac :: Integer -> [Integer]
fac x = take 1 $ map (x `mod` ) $ reverse [2 .. xs]
where xs = floor $ sqrt $ fromIntegral x
我想顯示[2 .. xs]
的第一個值,使x mod y == 0
。 但是我不能使用filter
因為那樣只會影響mod
的輸出。 我該怎么做呢?
我想顯示[2 .. xs]中的第一個值,以使x mod y == 0
在這種情況下,您不應該使用reverse
:
fac x = take 1 $ filter (\y -> x `mod` y == 0) $ reverse [2 .. xs]
where xs = floor $ sqrt $ fromIntegral x
如果要找出從xs
開始的第一個值,使mod xy == 0
,那么也不需要使用reverse
:
fac x = take 1 $ filter (\y -> x `mod` y == 0) $ [xs, xs-1 .. 2]
where xs = floor $ sqrt $ fromIntegral x
您可以使用filter
。 只需為filter
的第一個參數撰寫(==0)
和(x `mod`)
。
如果您嘗試做Euler項目問題3,這將是解決問題的一種非常痛苦的方式。
我建議以下內容:
為where
子句中的內容定義一個函數,即isqrt = round . sqrt . fromIntegral
isqrt = round . sqrt . fromIntegral
定義兩個函數isPrime
和primeList
是計算質數,你應該用相互遞歸isqrt
中的定義isPrime
,雖然使用的isqrt
實際上不是必要的; 我只是發現編寫此函數更容易考慮。 (以下是有關如何執行此步驟的提示)
使用primeList
,定義一個遞歸factorize
函數,該函數輸出素數(或類似物)列表
分解問題中的數字並返回列表中最大的素數
我上面的建議通常不能很快地計算出非常大的素數,但是對於這個問題應該足夠了。 本文詳細介紹了原因: http : //www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
對於與未來數論有關的PE問題,請研究使用此庫: https : //hackage.haskell.org/package/arithmoi-0.2.0.4
其他的建議:
而不是take 1
,您應該實際使用head
; 稍微好一點。
另外,由於此處要處理的最大數字是600851475143,因此實際上不需要該函數具有Integer- Integer -> [Integer]
。 32位Int
不能解決問題,因為maxBound :: Int
是2147483647。maxBound maxBound :: Int64
是9223372036854775807,這遠遠超出了您的需要。 因此,您可以僅將函數定義為Int64 -> [Int64]
(如果計算機已經是64位,則只需Int -> [Int]
)。
暗示:
primeList
應該定義為primeList = 2 : 3 : filter isPrime [5,7..]
,但是您可以根據自己的意願決定是否花哨。 同樣,這些定義應該是相互遞歸的。
fac x = take 1 $ filter (\y -> x `mod` y == 0 ) $ reverse [2 .. xs]
where xs = floor $ sqrt $ fromIntegral x
或者,要無意義:
fac x = take 1 $ filter ((== 0).(x `mod`)) $ reverse [2 .. xs]
where xs = floor $ sqrt $ fromIntegral x
不知道您是否要在這里reverse
,還是您的目標到底是什么。
您可以使用過濾器。 這是一線(如果算上進口的話,是兩線):
import Data.Ix (range)
fac x = head . filter ((==) 0 . mod x) . curry range 2 . floor . sqrt . fromIntegral $ x
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.