I’m new to Ruby and thought that it would be a great way to learn more by solving the problems at Project Euler.
Here’s what I came up with using brute force for Problem 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
This runs for a long time and gives no answer.
Then I used the same logic to write a C++ program to do the same task:
#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;
}
This one gives me the correct solution and runs for barely a second. The execution time doesn’t really concern me as Ruby is interpreted and C++ compiled but Ruby’s failure at returning the correct answer does surprise me. I think it might be because of me trying to write C++ Ruby style and not the actual Ruby way.
What am I doing wrong here?
Note: I have not run either of the proposed solutions below to completion – they still take a long time – so correctness is not guaranteed!
The line where you update
flagis the problem. You’re using&(bitwise-and) rather than&&(Boolean-and).Among other problems,
&has higher operator precedence than==, so your line is interpreted as (since? true : falseis redundant):Now, it appears that
true & some_integeristrue, which is not== 0, soflagis always set tofalse.Instead, you want:
or, more succinctly and Rubyish:
An alternative solution would be to do: