【发布时间】:2014-11-11 21:40:36
【问题描述】:
我正在再次处理 Project Euler 问题(在我学习 C# 之前做过前 23 个问题),我对问题 5 的解决方案表现不佳感到非常困惑。
内容如下:
2520 是可以除以每个数字的最小数字 从 1 到 10,没有任何余数。
能被所有人整除的最小正数是多少 从 1 到 20 的数字?
现在,我对 C# 的原始蛮力解决方案在大约 25 秒内解决了这个问题。
var numbers = Enumerable.Range(1, 20);
int start = 1;
int result;
while (true)
{
if (numbers.All(n => start % n == 0))
{
result = start;
break;
}
start++;
}
现在我的 F# 解决方案也使用了暴力破解,但至少它做了更多的区分,因此它“应该”在我的脑海中运行得更快,但它的时钟输出约为 45 秒,因此它的速度几乎是C# 一。
let p5BruteForce =
let divisors = List.toSeq ([3..20] |> List.rev)
let isDivOneToTwenty n =
let dividesBy =
divisors |> Seq.takeWhile(fun x -> n % x = 0)
Seq.length dividesBy = Seq.length divisors
let findNum n =
let rec loop n =
match isDivOneToTwenty n with
| true -> n
| false -> loop (n + 2)
loop n
findNum 2520
P.S - 我知道我的解决方案可能会更好,在这种情况下,我只是想知道一个更好的蛮力解决方案怎么会比原始解决方案慢得多。
【问题讨论】:
-
请注意,解也必须是 2520 的倍数。因此,您的增量可以是 2520,您将要测试的数字要少得多。即使使用简单的蛮力解决方案,它也会很快完成。此外,您不需要测试 1 到 10 的整除性。
-
不是C# / F# Performance comparison 的完全相同的副本。但它解释了为什么 F# 比 C# 慢
-
@L.B 真的吗?你要来这里对表演发表粗鲁的评论吗?我从未声称这是一个特别好的解决方案。不是每个人都天生具有出色的编码天赋,也许这就是我努力学习的原因?