I am using Project Euler problems to learn Haskell and I find a recurring theme in many of these problems where I need to find a value n
that gives some property (usually minimum or maximum) to a function fn
. As I build up a solution, I often find it convenient to create a list of pairs (n, fn)
. This helps me quickly see if I have any errors in my logic because I can check against the examples given in the problem statement. Then I "filter" out the single pair that gives the solution. My solution to problem 47 is an example:
-- Problem 47
import Data.List
import ProjectEuler
main = do
print (fst (head (filter (\(n, ds) -> (all (==consecutiveCount) ds))
(zip ns (map (map length)
(map (map primeDivisors) consecutives))))))
where consecutiveCount = 4
consecutive n start = take n [start..]
consecutives = map (consecutive consecutiveCount) ns
ns = [1..]
It seems to me that there's a more "haskelly" way to do this. Is there?
Use maximumBy
from Data.List
with comparing
from Data.Ord
, eg
maximumBy (comparing snd) [(n, f n) | n <- ns]
this will compute f
once for each n
. If f
is cheap to compute, you can go with the simpler
maximumBy (comparing f) ns
Well, you could write your function as
main = print $ fst $ head
[ (x,ds) | x <- [1..]
, let ds=map primeDivisors [x..x+3], all ((==4).length) ds]
You could consider it "more Haskelly" to use Control.Arrow
's (&&&)
, or "fan-out"
filter (all ((==4).length).snd)
. map (id &&& (\x-> map primeDivisors [x..x+3])) $ [1..]
To be able to tweak the code to try the simple examples first, you'd usually make it a function, abstracting over the variable(s) of interest, like so:
test n m = [ x | x <- [1..], all (==n) $ map (length.primeDivisors) [x..x+m-1]]
to search for m
consequitive numbers each having n
distinct prime factors. There is actually no need to carry the factorizations along in the final code.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.