需要提示项目欧拉问题

时间:2011-07-08 03:17:20

标签: haskell hint

从1到20的所有数字均可被整除的最小正数是多少?


我可以通过循环轻松地用强制性编程语言强制解决方案。但是我想在Haskell中做到这一点而不是让循环变得更难。我在考虑做这样的事情:

[n | n <- [1..], d <- [1..20], n `mod` d == 0] !! 0

但是我知道这不起作用,因为“d”会使条件在d = 1时等于True。我需要提示如何设置它以便为[1]计算n mod d。 .20]并且可以验证所有20个号码。

再次,请不要给我一个解决方案。谢谢。

7 个答案:

答案 0 :(得分:8)

与许多Project Euler问题一样,这至少与数学和编程一样重要。

您正在寻找的是一组数字中最不常见的倍数,它们恰好是从1开始的序列。

函数式语言中的一种可能的策略是试图使其递归,这是基于找出所有[1..n]可被整除的最小数字与[1..n+1]所有可被整除的最小数字之间的关系。用一些小于20的数字来玩这个,并尝试理解数学关系或者可能辨别出一种模式。

答案 1 :(得分:5)

在找到这样的数字之前,不要进行搜索,而是考虑一种建设性的算法,在给定一组数字的情况下,构造所有这些数字的smallest (or least) positive number that is evenly divisible by (aka "is a common multiple of")。查看那里的算法,并考虑Euclid's algorithm(他们提到的)可能适用的方式。

你能想到两个数字之间在最大公约数和最小公数之间的关系吗?一组数字怎么样?

答案 2 :(得分:4)

如果你看一下,它似乎是一个列表过滤操作。无限数列表,根据是否可以从1到20的所有数字整除的情况进行过滤。

所以我们得到的是我们需要一个函数,它接受一个整数和一个整数列表,并告诉它是否可以被列表中的所有数字整除

isDivisible :: [Int] -> Int -> Bool

然后在List过滤器中将其用作

filter (isDivisible [1..20]) [1..]

现在因为Haskell是一种懒惰的语言,你只需要从上面的过滤结果中获取所需数量的项目(在你的情况下你只需要一个,因此List.head方法听起来不错)。

我希望这会对你有所帮助。这是一个简单的解决方案,并且还有许多其他单线解决方案:)

答案 3 :(得分:1)

备选答案:您可以利用Prelude中提供的lcm功能。

答案 4 :(得分:0)

为了有效地解决这个问题,请选择Don Roby的答案。如果您只想对蛮力方法稍作提示,请将您写回的内容翻译成英文,并查看它与问题描述的区别。

你写了类似“过滤积极自然和积极自然的产物从1到20”

你想要的更像是“通过从1到20的正面自然的某些功能来过滤积极的自然”

答案 5 :(得分:0)

在这种情况下你必须得到Mathy。从累加器foldl开始,您将执行[1..20]n = 1。对于该列表的每个数字p,只有在p为素数时才会继续。现在,对于上一个素数p,您希望找到q这样的最大整数p^q <= 20。乘以n *= (p^q)。完成foldl后,n就是您想要的数字。

答案 6 :(得分:0)

可能的暴力实施将是

head [n|n <- [1..], all ((==0).(n `mod`)) [1..20]]

但在这种情况下,它会花费太长时间。 all函数测试谓词是否适用于列表的所有元素。 lambda是(\d -> mod n d == 0)的缩写。

那你怎么能加快计算速度呢?让我们将我们的除数归结为素数因子,并搜索每个素数因子的最高幂

2  = 2
3  =     3
4  = 2^2
5  =         5
6  = 2 * 3
7  =           7
8  = 2^3
9  =     3^2
10 = 2     * 5
11 =             11
12 = 2^2*3
13 =                13
14 = 2        *7
15 =     3 * 5
16 = 2^4
17 =                   17
18 = 2 * 3^2
19 =                      19
20 = 2^2   * 5
--------------------------------
max= 2^4*3^2*5*7*11*13*17*19     

使用此号码我们有:

all ((==0).(2^4*3^2*5*7*11*13*17*19 `mod`)) [1..20]
--True
嘿,它可以从1到20的所有数字整除。不是很令人惊讶。例如。它可以被15整除,因为它“包含”因子3和5,它可以被16整除,因为它“包含”因子2 ^ 4。但这是最小的数字吗?想一想......