Created
July 7, 2012 19:16
-
-
Save raghubetina/3067729 to your computer and use it in GitHub Desktop.
Project Euler Problem 1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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