Sunday, September 22, 2013

Proud of myself - Smallest Multiple

In an effort to learn Ruby in a semi-fun way, I'm porting my Project Euler solutions that are in Groovy to Ruby.

Today I made myself proud...

Problem 5 - Smallest Multiple

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?

My Groovy solution:

class Test extends GroovyTestCase {
 
 def solveFor(upperBound) {
  def answer = 0
  def temp = upperBound * (upperBound + 1)
  while(true) {
   answer = temp
   (2..upperBound).each {
    if(temp % it != 0) {
     answer = 0
     return
    }
   }
   if(answer != 0) {
    return answer
   }
   temp += upperBound
  }
 }
 
 void test_base_case() {
  assertEquals 2520, solveFor(10)
 }
 
 void test_solution() {
  def start = System.currentTimeMillis()
  println solveFor(20)
  def end = System.currentTimeMillis()
  println "Elapsed time ${end - start} milliseconds"
 }
}  

To this Ruby solution:


require "test/unit"

def solve_for(upper)
  answer = upper
  until divisible_by_numbers_up_to?(answer, upper)  do
    answer += upper
  end
  answer
end

def divisible_by_numbers_up_to?(number, upper)
  (2..upper).all? { |i| number % i == 0 }
end

class SolveProblemXTests < Test::Unit::TestCase

  def test_simple_case
    solution = solve_for(2)
    assert_equal(2, solution, "Solution was #{solution} not 2520")  end


  def test_base_case
    solution = solve_for(10)
    assert_equal(2520, solution, "Solution was #{solution} not 2520")
  end

end

answer = solve_for(20)

puts "Answer is #{answer}"


After some thinking I felt it was still a little clunky and I actually wanted to try to make it more terse for fun. So I left the tests etc. but changed the implementation at top of file to this:


def solve_for(upper)
  (upper..Float::INFINITY).step(upper).find do |num|
    (2..upper).all? { |i| num % i == 0 }
  end
end

Not sure it got more confusing to read. Earlier code was not necessarily easiest to read but I learned some stuff about Ruby and coding in general. Honestly it was my exposure to Clojure that made me think I could use a lazy loaded list of numbers going to infinity.

Mission Accomplished!

No comments:

Post a Comment