了解Ruby的逻辑运算符
我是新来的Ruby,并认为这将是学会解决在项目欧拉的问题更多的好方法。了解Ruby的逻辑运算符
这就是我想出了使用暴力的问题5:
#What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
end_point = 1_000_000_000
start_point = 2_520
(start_point..end_point).each do |number|
flag = true
(2..20).each do |divisor|
flag = flag & (number % divisor) == 0 ? true : false
end
print number.to_s + "\n" if flag
end
它运行很长一段时间,并没有给出答案。
然后我用同样的逻辑来写C++程序做同样的任务:
#include<iostream>
using namespace std;
int main()
{
unsigned long int solution = 2520;
while(1)
{
bool flag = true;
for(int divisor=2;divisor<=20;divisor++)
{
if(solution % divisor == 0)
flag = flag & true;
else{
flag = false;
break;
}
}
if(flag == true){
cout<<solution<<endl;
break;
}
solution++;
}
return 0;
}
这一次给了我正确的解决方案并运行几乎没有第二个。执行时间并不关心我,因为Ruby被解释和C++编译,但Ruby在返回正确答案方面的失败让我感到惊讶。我认为这可能是因为我试图编写C++ Ruby风格,而不是实际的Ruby方式。
我在这里做错了什么?
注:我还没有运行,下面无论是提出的解决方案来完成 - 他们仍然需要很长的时间 - 所以正确性不能保证!
,你更新flag
该生产线的问题。您正在使用&
(按位与),而不是&&
(布尔和)。
在其他问题,&
比==
更高的运算符优先级,让你的行被解释为(因为? true : false
是多余的):
flag = (flag & (number % divisor)) == 0
现在看来true & some_integer
是true
,这是不== 0
,因此flag
始终设置为false
。
相反,你想:
flag = flag && (number % divisor == 0)
,或者更简洁和Rubyish:
flag &&= number % divisor == 0
另一种解决办法是要做到:
i = 1
while true
break unless (2..20).any? {|d| i % d != 0}
i+=1
end
puts i
我其实解决了这个问题无需为它编写程序。 这是我使用的逻辑:
写下所有质数小于20(目标)。
[2, 3, 5, 7, 11, 13, 17, 19]
对于每个素数,它提升到对于其比目标(20)更小的最大功率。
2**4 * 3**2 * 5 * 7 * 11 * 13 * 17 * 19
对于做编程方式使用埃拉托色尼的筛 - http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes算法遍历素数。对于列表中的每个素数,找出获得小于目标数的最大功率(20)。你可以找到使用这个公式的力量:(Math.log(target)/Math.log(i)).floor
假设你得到的素数的数组:使用此nums = [2, 3, 5, 7, 11, 13, 17, 19]
然后你就可以得到答案很容易:
nums.map {|i| i**((Math.log(target)/Math.log(i)).floor)}.inject(:*)
您的替代解决方案正是我正在寻找, 人们如何编写比我能够在红宝石上更美丽的代码,这不是太好了吗?我想知道我该如何真正学习这种红宝石方式。 – nikhil 2011-06-14 09:27:18
你能告诉我&&和'和'之间的区别吗?最初我使用'和',因为这不起作用,我试过&。 – nikhil 2011-06-14 09:31:38
不客气。我认为这里的相关思想是Ruby喜欢直接用集合来做事情;也就是说,在Enumerable上调用隐式循环方法比在显式循环内容上更鲁莽。顺便说一下,这两种方法都给出了正确的答案,但我的速度更快(因为任何一种方法一旦失败就会短路)。 – Chowlett 2011-06-14 09:32:58