Skip to content

Instantly share code, notes, and snippets.

@raghubetina
Created July 7, 2012 19:16
Show Gist options
  • Save raghubetina/3067729 to your computer and use it in GitHub Desktop.
Save raghubetina/3067729 to your computer and use it in GitHub Desktop.
Project Euler Problem 1
# My solution:
# First, a helper method:
def is_a_multiple_of?(factor, candidate)
return candidate % factor == 0
end
sum = 0 # I read this as:
1.upto(999) do |number| # "From 1 upto 999, for each number,"
if is_a_multiple_of?(3, number) # "If the number is a multiple of 3"
sum += number # "Increase sum by the number."
elsif is_a_multiple_of?(5, number) # "Else, if the number is a multiple of 5"
sum += number # "Increase sum by the number."
end
end
puts sum
# This solution is a direct translation of the steps I took when I solved the example problem with pen and paper. First I figured out what it even means for a number to be a multiple of another number. Then I looked at each number from 1 to 9 and checked if it was a multiple of 3 and added it to my running total if it was; otherwise, I checked if it was a multiple of 5 and added it to my running total if it was.
# Also, the above code reads like English to me (Yoda English -- even better).
# For these two reasons, the above solution is the easiest for me to comprehend. Therefore, it is my favorite.
# However, here are some of my other solutions in case you want to stretch your Ruby vocabulary.
##### Using Arrays #####
multiples_of_three = Array.new
multiples_of_five = Array.new
multiples_of_fifteen = Array.new
1000.times do |this_number|
if this_number % 3 == 0
multiples_of_three << this_number
end
if this_number % 5 == 0
multiples_of_five << this_number
end
if this_number % 15 == 0
multiples_of_fifteen << this_number
end
end
def sum(array_of_numbers)
sum = 0
array_of_numbers.each do |number|
sum += number
end
return sum
end
puts sum(multiples_of_three) + sum(multiples_of_five) - sum(multiples_of_fifteen)
# This solution has some strange, roundabout logic going on. Subtracting multiples of 15? Why does this work?
##### Briefer Array Solution ######
# When you see ugly code like the below with crazy method chaining going on, don't panic. Remember, the interpreter looks at each expression one at a time, checks what it boils down to, and then plugs that into the next part. Break it up into pieces and refer to the docs to see how unfamiliar methods work.
multiples_of_3 = Array.new((1000.0/3).ceil) do |i|
i * 3
end
multiples_of_5 = Array.new((1000.0/5).ceil) { |i| i * 5 }
multiples_of_15 = Array.new((1000.0/15).ceil) { |i| i * 15 }
puts sum(multiples_of_3) + sum(multiples_of_5) - sum(multiples_of_15)
# What type of object am I calling .ceil on? Therefore, where will the description of that method be in the docs? I bet you didn't know you could pass arguments and even a block of code to Array#new; go check the docs to see what all you can do.
# By the way, the curly braces you see are not hashes; if you use them next to methods that can accept do-end blocks, then they are just shorthand for do-end. But they only work for one-line blocks of code.
##### Introducing the Ruby Range, .inject, and the ternary operator #####
puts (1...1000).inject(0) { |result, n| n % 3 == 0 || n % 5 == 0 ? result += n : result }
# There's a lot of new stuff in this one line of code.
# - Why is it okay to have the puts on the same line?
# - What is the (x...y) syntax doing? What's the difference between that and (x..y)? What types of values work for x and y in such syntax?
# - What's up with the .inject method? How does it differ from .each?
# - What's this a ? b : c craziness?
##### Introducing .step, .uniq, and .inject(:+) #####
multiples = Array.new
(0...1000).step(3) { |n| multiples.push(n) }
(0...1000).step(5) { |n| multiples.push(n) }
puts multiples.uniq.inject(:+)
##### Introducing .select #####
puts (0...1000).select { |n| n % 3 == 0 || n % 5 == 0 }.inject(:+)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment