了解Ruby逻辑运算符

问题描述

| 我是Ruby的新手,并认为这是通过解决Euler项目中的问题而学习更多的好方法。 这是我对问题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
要以编程方式执行此操作,请使用Eratosthenes筛-http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes算法对素数进行迭代。对于列表中的每个质数,找到将其提高到小于目标数(20)的最大幂。您可以使用以下公式找到幂:
(Math.log(target)/Math.log(i)).floor
假设您得到素数数组:
nums = [2,19]
然后,您可以使用以下方法轻松获得答案:
nums.map {|i| i**((Math.log(target)/Math.log(i)).floor)}.inject(:*)