Ruby quiz n.93

From: Eric Torreborre <etorreborre@yahoo.com>
Date: September 5, 2006 3:44:14 PM CDT
To: submission@rubyquiz.com
Subject: Ruby quiz n.93
Reply-To: Eric Torreborre <etorreborre@yahoo.com>

Hi,

Here is my solution to this week quiz:

-I used rspec (the more I use it, the more I like it)
-I created an EmotiveNumber class, knowing if he's happy or sad (to add some feelings to this rational world)

I haven't found drastic improvements on my laptop by using knowledge such as the cyclic numbers ([4, 16, 37, 58, 89, 145, 42, 20]) or caching suites for existing happy numbers (around 220 s. for the 1.000.000 "happiest number" search ). Anyway, this quiz was really fun, thank you.

===============================
The spec.

require "spec"
require "happy_numbers"

context "A happy number method" do
  specify "should say 1 is a happy number" do
    1.happy_number?.should_be true
  end

  specify "should say 2 and 3 are not happy numbers" do
    [2, 3].each{|n| n.happy_number?.should_be false}
  end

  specify "should say 7, 10 are happy numbers" do
    [7, 10].each{|n| n.happy_number?.should_be true}
  end

end

context "A find happy numbers function" do
  specify "should find the correct happy numbers from 1 to 10" do
    find_happy_numbers(10).should_equal([1, 7, 10])
  end
end

context "A find happiest number function" do
  specify "should find the happiest number from 1 to 10" do
    find_happiest_number(10).should_equal(7)
  end

  specify "should find the happiest number from 1 to 1000000" do
    find_happiest_number(1000000).should_equal(78999)
  end
end

The code: happy_numbers.rb

require "emotive_number"

class Fixnum
  def happy_number?
    EmotiveNumber.new(self).happy?
  end
end

def find_happy_numbers(n)
  (1..n).select{|seed| seed.happy_number?}
end

def find_happiest_number(n)
  happiest, max_size = 1, 1
  (1..n).each do |seed|
    emotive = EmotiveNumber.new(seed)
    happiest, max_size = seed, emotive.size if (emotive.happy? && emotive.size > max_size)
  end
  return happiest
end

The code: emotive_number.rb

  class EmotiveNumber
  CYCLIC_NUMBERS = [4, 16, 37, 58, 89, 145, 42, 20]
  attr_reader :suite

  def initialize(seed)
    @suite =
    compute_suite(seed)
  end

  def happy?
    suite.last == 1
  end

  def size
    suite.size
  end

private

  def compute_suite(seed)
    next_element = seed
    while (!happy? && !CYCLIC_NUMBERS.include?(next_element))
      @suite << next_element
      next_element = square_sum(@suite.last)
    end
    @suite += CYCLIC_NUMBERS if !happy?
  end

  def square_sum(num)
    num.to_s.split(//).inject(0){|result, i| result += i.to_i*i.to_i}
  end
end

===============================
--------------------------------------------------
Eric Torreborre
LTG - Product Manager
LEIRIOS
tel: 33(0)6.61.48.57.65/33(0)3.81.88.62.02
e-mail: etorreborre@yahoo.com
blog: http://etorreborre.blogspot.com
--------------------------------------------------

···

Begin forwarded message: