Skip to main content

Venturing into Number Theory

In attempt to solve a maths problem with Ruby, I discovered the benefits of going beyond simple arithmetic. Perhaps surprisingly, many seemingly complex mathematical problems can be solved using basic arithmetic and raw computing power. Most of the time this doesn't pose a problem. However, as the values involved grow larger, the demands on the computer's memory reaches a critical point beyond which you risk crashing your computer. 

The problem I was trying to solve was the following:


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

After causing my computer to hang for several minutes, I realized I had to rewrite the program I was working on. The program had to take shortcuts, so that instead of testing every single value between 1 and 1 million, it only tested likely values. With the help of my lovely wife (a Maths teacher) I rewrote the program using prime numbers.  

class SmallestProduct

require 'prime'

  def initialize(target)
    @target = target
    @primes=[]
    @divisors = []
  end

  def primes_finder
    Prime.each(@target) {|prime| @primes<<prime}
    @primes
  end

  def divisor_finder

    power_max = (@target ** 0.5).floor
    @primes.each do |prime|
      identified=false
      n = power_max
      until identified
        if prime**n < @target
          @divisors << prime ** n
          identified = true
        end
        n-=1
      end
    end
    @divisors
  end

  def product_finder
    smallest = 1
    @divisors.collect {|divisor| smallest *= divisor}
    puts "The smallest number divisible by all numbers from 1 to         your test value is:
     #{smallest}"
  end
end

  def user_input
    puts
    puts "This program finds the smallest number that is evenly         divisible by all numbers between 1 and a value of your choice."
    puts
    puts "What value are you interested in testing: "
    choice = STDIN.gets.to_i
    search = SmallestProduct.new(choice)
    search.primes_finder
    search.divisor_finder
    search.product_finder
  end


  user_input

The 'workhorse' of this program is the divisor_finder method. 
  1. It starts with the array of primes created by the prime_finder. (e.g. primes under 10 = [2,3,5,7])
  2. It then creates a variable called power_max which is the nearest integer square root of the target value. (e.g. if your target is 10, power_max would be 3.)
  3. It then raises each of the primes from prime_finder to power_max. If the result is under the target, the result is stored in the divisors array. (e.g. 2^3 = 8, therefore 8 becomes a divisor). If the prime raised to power_max is above the target, power_max is reduced by 1 and a new test is made.  (e.g. prime = 3; 3^3 =27, which is above 10. So 3^2 tested which equals 9 which is below 10. Therefore 9 becomes a  divisor.) 
  4. Why do we do this? If a number is divisible by 8, then it is divisible by 4 and by 2. So if we're trying to find a number divisible by all values from 1 to 10, we don't need to go through and test 1 to 10 every time. If the number is evenly divisible by 8, we skip 4 and 2. If it's divisible by 9 we skip 3 and so on. Still working with 10, the divisors we would be left with are [5,7,8,9]
  5. Once all divisors have been identified, the magic happens. If you multiply the identified divisors by each other, you get the smallest product divisible by all numbers from 1 to your target.So 5 x 7 x 8 x 9 = 2520. 2520 is the smallest number divisible by all numbers from 1 to 10.
     
Magic!

Comments

Popular posts from this blog

Ruby, RSpec, Linux and Relational Algebra (or "What I'm doing this Christmas")

Last week was challenging- I'm beginning to appreciate the need for a programming buddy.  So far, I haven't found a Ruby IDE that helps with missing brackets or illegal syntax. This means hours spent looking for errors which more experience (or an IDE) would have solved in an instant. I've spent a lot of time on Stack Exchange looking for solutions to problems that many have already had- so far I haven't had to post a single new question (though it's evident that many people post duplicate questions, not having looked for a solution first). I spent longer on the Ruby project than anticipated, BUT I really enjoyed learning about Behaviour Driven Development. Thinking of tests in RSpec and then watching my Ruby script pass (eventually) was like passing an exam (though  one I had written myself). This week I'll be starting Rails-after I complete the CodeSchool Rails courses I'll go on to their RSpec course. Partly for the geek cred, partly out of curiosit...

Rails Project-Blogger Problem

Ran into my first challenge with the blogger today. I was creating a new model for a Comment feature and I typed: $ bin/rails generate model Comment author_name:string body:text article s :references That single red letter cost me an hour of struggle (I mean 'learning'). The extra s created a database schema containing something called 'articles_id'.  Since id  is a property of a single article, the comment controller  couldn't find an id  for articles,  as it didn't exist.  I looked at the Comment model file and saw the extra s  almost immediately after trying to enter a comment. But then I couldn't reverse the error. Rolling back the migration ( rake db:rollback), had no effect on the schema.  Destroying the model ( rails destroy model Comment)  had no effect on the schema. In the end I replaced the my local files with the Github repo contents (luckily I had just done a push). git fetch --all git reset --hard or...

CodeSchool vs Codecademy(or 'How socket inherits event listening methods and implements asynchronicity')

In this review I'm going to focus on the pedagogy that I see evident in some CodeSchool courses and compare them to  Codecademy. By pedagogy, I mean: 'How does CodeSchool teach?' and ' Does it do a good job of teaching?'. I'm going to argue that despite high quality videos, colourful web pages, and often ssspppeeeeeakkkiiiing...rrrreeally...slowly..., CodeSchool's pedagogy is inferior to that of Codecademy. There are many fantastic resources for learning to code on the web, and CodeSchool is one of them. So far I have completed courses in Ruby, Rails, Javascript, HTML/CSS, Jquery and Git on CodeSchool. The courses have all included high quality videos and colourful, interactive exercises- as well as  massive  pdf files of the slides ( the files take more than a minute to load on my machine .) The question is: does the higher production value mean better educational quality? The 'Try' courses on CodeSchool(such as Try Ruby and Try jQuery) are f...