Project Euler 1-5 (Ruby)
projecteuler.net tries to get you thinking about how to solve mathematical problems by programming. Here are the first five problems, solved in Ruby, including comments.
1 2 3 4 5 6 7 8 9 10 11 12
# https://projecteuler.net/index.php?section=problems&id=1 # look at the first 1000 numbers and add those to the sum # that are multiples of 3 or 5 sum = 0 # initial sum 1000.times{ |n| # iteration index (0-999) sum += n if n%3==0 || # add to sum if divisible by n%5==0 # 3 or 5 without rest } puts sum
1 2 3 4 5 6 7 8 9 10 11 12
# https://projecteuler.net/index.php?section=problems&id=2 # calculate fibonacci (non-recursive) and sum all even values n=m = 1 # first two fib. numbers sum = 0 # initial sum while m < 4_000_000 # as long as fib. sequence is < 4 000 000 n,m = m,n+m # calculate next step (sum of the prev. 2 numbers) sum += n if n.even? # add to sum if even [ruby 1.9] end puts sum
1 2 3 4 5 6 7 8 9 10 11 12 13
# https://projecteuler.net/index.php?section=problems&id=3 # find the largest prime factor of 600 851 475 143 a = 600_851_475_143 f = 2 # smallest possible prime factor # Divide "evil big number" by lowest prime factors to get the # biggest one. Prime factors are the numbers, which do not # leave a rest. If a possible number is not a prime factor # candidate anymore, check the next one. a%f==0 ? a/=f : f+=1 while a>1 puts f
1 2 3 4 5 6 7 8 9 10 11 12 13
# https://projecteuler.net/index.php?section=problems&id=4 # find the largest palindrome made from xxx*xxx products = # get an array of ALL xxx*xxx (100..999).map{ |a| (100..999).map{ |b| a*b } }.flatten.select{ |p| # select those, which are reversed p.to_s == p.to_s.reverse # the same as non-reversed }.sort.reverse # sort them and reverse result puts products[0] # put out first (and largest) palindrome
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# https://projecteuler.net/index.php?section=problems&id=5 # find a number that you can divide by 1..20 # using the method described at the solution sheet at euler # needed input till = 20 primes = [2,3,5,7,11,13,17,19] # get factor for each prime factors = primes.map{ |f| f > (limit ||= till**0.5) ? 1 : # only calcutlate if f < square root of till ( Math.log(20)/Math.log(f) ).to_i # calc using log (see euler sheet) } # now multiply all primes**factors number = 1 p = primes.each # init extern iterators f = factors.each loop{ number *= p.next**f.next } # loop breaks when StopIteration is raised # output puts number
Bob | January 18, 2010
For problem 1, the following solution is more in the spirit of Ruby, IMHO:
puts (1...1000).select {|n| n % 3 == 0 || n % 5 == 0}.inject(0) {|s, n| s + n}
J-_-L | January 18, 2010
Although I think, the Listing 1 method is the easist-to-understand method, I agree, your way is more Ruby-like. In Ruby 1.9 / 1.87 you can even write it further significant: puts (1...1000).select{|n| n % 3 == 0 || n % 5 == 0}.inject(:+)
Mark | August 02, 2010
Or...
(1...1000).reduce(0) do |sum,n|
sum += n if n % 3 == 0 || n % 5 == 0
sum
end
Juan Romero Abelleira | June 04, 2011
Or instead of brute forcing the problem you could modify the steps through the range:
puts (0...1000).step(3).to_a.concat((0...1000).step(5).to_a).inject(:+)
J-_-L | June 13, 2011
@Juan Nice approach :D (but you need to add uniq). A cool 1.9.2 rewrite may be: <code>[*(0...1000).step(3),*(0...1000).step(5)].uniq.inject(:+)</code>