# Project Euler Series: Problem 1

## July 28, 2016

## Dylan Richards

Solving the problems on Projet Euler is a great way to dive into programming. In this post, I’d like to solve Problem 1, while covering some Ruby language fundamentals. We’ll look at three different approaches to solving the same problem.

Let’s get started.

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.

# Iteration 1

The first thing we’ll need is a collection of numbers from 1 to 999.

` ````
numbers = (1..999).to_a # => [1, 2, 3, 4, ..., ..., 999]
```

Next, we’ll need a starting value.

` ````
answer = 0
```

Here’s the fun part. Let’s use an each loop to iterate over each of those numbers.

` ````
numbers.each do |number|
end
```

Every time we encounter a number that’s a multiple of either 3 or 5, we need to increment the answer value.

` ````
if number % 3 == 0 || number % 5 == 0
answer += number # => Add the number to the eventual answer if it's evenly divisible by 3 or 5
end
```

You should now have this:

` ````
numbers = (1..999).to_a
answer = 0
numbers.each do |number|
if number % 3 == 0 || number % 5 == 0
answer += number
end
end
```

Now we just need to return the answer.

` ````
p answer # => 233168
```

Done.

We can do better, though. Whenever you find yourself creating an empty array,
putting items into it, then finally returning it, there may be an opportunity to use **Array#map**.
**#map** creates a new array containing the values returned by the block. Check it out:

# Iteration 2

` ````
numbers = (1..999).to_a.map { |num| num if num % 3 == 0 || num % 5 == 0 }
```

The code above takes the array of numbers 1-999 and creates a new array of elements that match the condition in the block. In this case, it will be numbers that are evenly divisible by 3 or 5.

Let’s sum them up.

` ````
numbers.reduce(&:+)
```

Wait – What’s this?

` ````
euler-1.rb:5:in each: undefined method '+' for nil:NilClass (NoMethodError)
from euler-1.rb:5:in reduce
from euler-1.rb:5:in main
```

This error is telling us that the addition method isn’t available on an element in
our array, which happens to be nil. Why are there nil elements in the array? Simple.
Our **map** returned nil for each element that didn’t match the condition.

Before we can sum the array, we must first remove the nil elements with **Array#compact**.

` ````
numbers.compact.reduce(&:+) #=> 233168
```

And there you have it.

# Iteration 3

We can still do *a little bit better*, though. **Array#select** allows us to, well,
*select* elements in an array that match a condition. It won’t return nil for elements that don’t
match, which will save us from having to remove nil elements from the array before adding them up.

` ````
p (1..999).select { |num| num % 3 == 0 || num % 5 == 0 }.reduce(:+) #=> 233168
```

And that’s it.