如何为 Haskell 中的函数提供特定范围的输入
How to provide a specific range of inputs to a function in Haskell
我是 Haskell 的新手,我想知道是否可以提供前 51 个素数的范围作为输入而不是键入素数,请参阅第 2 行?
如果是,请修改代码和post解决方案。
1 perfect_nums n = (2^(n-1)) * ((2^n)-1)
2 fperfect_nums = [perfect_nums x | x <- [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233]]
3 main = print $ fperfect_nums
您可以编写生成素数的函数或使用库。为此,我喜欢使用 arithmoi
:
import Math.NumberTheory.Primes (nextPrime, unPrime)
perfectNums :: Integer -> Integer
perfectNums n = (2^(n-1)) * ((2^n)-1)
fperfectNums :: [Integer]
fperfectNums = [perfectNums (unPrime x) | x <- take 51 [nextPrime 0 ..]]
main :: IO ()
main = print fperfectNums
你已经有了
fperfect_nums = [perfect_nums x | x <- [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233]]
= [perfect_nums x | x <- primes51]
primes51 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233]
也就是
= take 51 $ [2 .. 288] `minus`
[4, 6 .. 288] `minus` -- all the multiples of 2 in the range
[9, 12 .. 288] `minus` -- all the multiples of 3 in the range
[25, 30 .. 288] `minus` -- and of 5, 7, 11, ...
[49, 56 .. 288] `minus` -- until we see that
[121, 132 .. 288] `minus` -- 13*13 = 169 whereas
[169, 182 .. 288] -- 17*17 = 289 which is above 233
= take 51 $ [2 .. 288] `minus`
(let {p=2} in [p*p, p*p+p .. 288]) `minus`
(let {p=3} in [p*p, p*p+p .. 288]) `minus`
(let {p=5} in [p*p, p*p+p .. 288]) `minus`
(let {p=7} in [p*p, p*p+p .. 288]) `minus`
(let {p=11} in [p*p, p*p+p .. 288]) `minus` -- 13*13 = 169
(let {p=13} in [p*p, p*p+p .. 288]) -- 17*17 = 289
= take 51 $ [2 .. 288] `minus` (
(let {p=2} in [p*p, p*p+p .. 288]) `union`
(let {p=3} in [p*p, p*p+p .. 288]) `union`
(let {p=5} in [p*p, p*p+p .. 288]) `union`
(let {p=7} in [p*p, p*p+p .. 288]) `union`
(let {p=11} in [p*p, p*p+p .. 288]) `union`
(let {p=13} in [p*p, p*p+p .. 288]) )
= take 51 $ [2 .. 288] `minus` ( foldr1 union
[[p*p, p*p+p .. 288] | p <- [2,3,5,7,11,13]] )
minus xs ys = [ x | x <- xs, not (elem x ys)]
union xs ys = xs ++ ys
所以是的,确实可以提供前 51 个质数的范围作为输入,而不是自己键入所有 51 个质数。为此,您只需要自己输入前 6 个质数。
你实际上有 61 个,
primesTo288 = 2 : [3 .. 288] `minus` ( foldr1 union
[[p*p, p*p+p .. 288] | p <- [2,3,5,7,11,13]] )
= 2 : 3 : [5,7 .. 288] `minus` ( foldr1 union
[[p*p, p*p+2*p .. 288] | p <- [3,5,7,11,13]] )
现在让它无界....
我是 Haskell 的新手,我想知道是否可以提供前 51 个素数的范围作为输入而不是键入素数,请参阅第 2 行?
如果是,请修改代码和post解决方案。
1 perfect_nums n = (2^(n-1)) * ((2^n)-1)
2 fperfect_nums = [perfect_nums x | x <- [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233]]
3 main = print $ fperfect_nums
您可以编写生成素数的函数或使用库。为此,我喜欢使用 arithmoi
:
import Math.NumberTheory.Primes (nextPrime, unPrime)
perfectNums :: Integer -> Integer
perfectNums n = (2^(n-1)) * ((2^n)-1)
fperfectNums :: [Integer]
fperfectNums = [perfectNums (unPrime x) | x <- take 51 [nextPrime 0 ..]]
main :: IO ()
main = print fperfectNums
你已经有了
fperfect_nums = [perfect_nums x | x <- [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233]]
= [perfect_nums x | x <- primes51]
primes51 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233]
也就是
= take 51 $ [2 .. 288] `minus`
[4, 6 .. 288] `minus` -- all the multiples of 2 in the range
[9, 12 .. 288] `minus` -- all the multiples of 3 in the range
[25, 30 .. 288] `minus` -- and of 5, 7, 11, ...
[49, 56 .. 288] `minus` -- until we see that
[121, 132 .. 288] `minus` -- 13*13 = 169 whereas
[169, 182 .. 288] -- 17*17 = 289 which is above 233
= take 51 $ [2 .. 288] `minus`
(let {p=2} in [p*p, p*p+p .. 288]) `minus`
(let {p=3} in [p*p, p*p+p .. 288]) `minus`
(let {p=5} in [p*p, p*p+p .. 288]) `minus`
(let {p=7} in [p*p, p*p+p .. 288]) `minus`
(let {p=11} in [p*p, p*p+p .. 288]) `minus` -- 13*13 = 169
(let {p=13} in [p*p, p*p+p .. 288]) -- 17*17 = 289
= take 51 $ [2 .. 288] `minus` (
(let {p=2} in [p*p, p*p+p .. 288]) `union`
(let {p=3} in [p*p, p*p+p .. 288]) `union`
(let {p=5} in [p*p, p*p+p .. 288]) `union`
(let {p=7} in [p*p, p*p+p .. 288]) `union`
(let {p=11} in [p*p, p*p+p .. 288]) `union`
(let {p=13} in [p*p, p*p+p .. 288]) )
= take 51 $ [2 .. 288] `minus` ( foldr1 union
[[p*p, p*p+p .. 288] | p <- [2,3,5,7,11,13]] )
minus xs ys = [ x | x <- xs, not (elem x ys)]
union xs ys = xs ++ ys
所以是的,确实可以提供前 51 个质数的范围作为输入,而不是自己键入所有 51 个质数。为此,您只需要自己输入前 6 个质数。
你实际上有 61 个,
primesTo288 = 2 : [3 .. 288] `minus` ( foldr1 union
[[p*p, p*p+p .. 288] | p <- [2,3,5,7,11,13]] )
= 2 : 3 : [5,7 .. 288] `minus` ( foldr1 union
[[p*p, p*p+2*p .. 288] | p <- [3,5,7,11,13]] )
现在让它无界....