3

I'm new to Haskell, started learning a couple of days ago and I have a question on a function I'm trying to make.

I want to make a function that verifies if x is a factor of n (ex: 375 has these factors: 1, 3, 5, 15, 25, 75, 125 and 375), then removes the 1 and then the number itself and finally verifies if the number of odd numbers in that list is equal to the number of even numbers!

I thought of making a functions like so to calculate the first part:

factor n = [x | x <- [1..n], n `mod`x == 0]

But if I put this on the prompt it will say Not in scope 'n'. The idea was to input a number like 375 so it would calculate the list. What I'm I doing wrong? I've seen functions being put in the prompt like this, in books.

Then to take the elements I spoke of I was thinking of doing tail and then init to the list. You think it's a good idea?

And finally I thought of making an if statement to verify the last part. For example, in Java, we'd make something like:

(x % 2 == 0)? even++ : odd++; // (I'm a beginner to Java as well)

and then if even = odd then it would say that all conditions were verified (we had a quantity of even numbers equal to the odd numbers)

But in Haskell, as variables are immutable, how would I do the something++ thing?

Thanks for any help you can give :)

4

5 回答 5

5

这个小功能可以完成您想要实现的一切:

f n = length evenFactors == length oddFactors
  where evenFactors = [x | x <- [2, 4..(n-1)], n `mod` x == 0]
        oddFactors  = [x | x <- [3, 5..(n-1)], n `mod` x == 0]
于 2013-09-23T00:05:04.870 回答
3

如果“命令行”是 ghci,那么你需要

let factor n = [x | x <- [2..(n-1)], n `mod` x == 0]

在这种特殊情况下,您不需要范围 [1..n] 仅删除 1 和 n - 范围从 2 到 (n-1) 。

您可以简单地使用 partition 使用布尔谓词拆分除数列表:

import Data.List
partition odd $ factor 10

为了学习如何编写类似的函数partition,请学习递归。

例如:

partition p = foldr f ([],[]) where
  f x ~(ys,ns) | p x = (x:ys,ns)
  f x ~(ys,ns) = (ys, x:ns)

(这里我们需要使用“~”懒惰地对元组进行模式匹配,以确保在构建右侧的元组之前不对模式进行评估)。

简单的计数可以更简单地实现:

let y = factor 375
(length $ filter odd y) == (length y - (length $ filter odd y))
于 2013-09-22T23:16:33.230 回答
2

创建一个文件 source.hs,然后从 ghci 命令行调用:l source来加载 source.hs 中定义的函数。

为了解决您的问题,这可能是按照您的步骤的解决方案:

-- computers the factors of n, gets the tail (strips 1)
-- the filter functions removes n from the list
factor n = filter (/= n) (tail [x | x <- [1..n], n `mod` x == 0])

-- checks if the number of odd and even factors is equal
oe n = let factors = factor n in 
           length (filter odd factors) == length (filter even factors)

调用oe 10返回Trueoe 15返回False

于 2013-09-22T17:34:37.517 回答
1
(x % 2 == 0)? even++ : odd++;

我们有Data.List一个partition :: (a -> Bool) -> [a] -> ([a], [a])函数

所以我们可以像这样划分赔率

> let (odds,evens) = partition odd [1..]

> take 10 odds
 [1,3,5,7,9,11,13,15,17,19]
> take 10 evens
 [2,4,6,8,10,12,14,16,18,20]
于 2013-09-22T21:02:11.957 回答
0

这是您factor尝试使用理解的最小修复:

factor nn = [x | n <- [1..nn], x <- [1..n], n `mod`x == 0]
于 2013-09-22T20:44:21.480 回答