Skip to content

Instantly share code, notes, and snippets.

@sowasred2012
Created May 21, 2014 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sowasred2012/1f3a2e5bd9275d4a7957 to your computer and use it in GitHub Desktop.
Save sowasred2012/1f3a2e5bd9275d4a7957 to your computer and use it in GitHub Desktop.
NumberLetterCounts Kata (Project Euler)
If the numbers 1 to 5 are written out in words: one, two, three, four, five
then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE:
Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.
class NumberLetterCounts
def self.calc(first, last)
count = 0
(first..last).each do |number|
str_number = number_to_string(number)
count += str_number.length
end
count
end
def self.number_to_string(number)
NumberString.new(number).to_s
end
class NumberString
NUMBER_TO_STRING = {
1 => "one",
2 => "two",
3 => "three",
4 => "four",
5 => "five",
6 => "six",
7 => "seven",
8 => "eight",
9 => "nine",
10 => "ten",
11 => "eleven",
12 => "twelve",
13 => "thirteen",
14 => "fourteen",
15 => "fifteen",
16 => "sixteen",
17 => "seventeen",
18 => "eighteen",
19 => "nineteen",
20 => "twenty",
30 => "thirty",
40 => "forty",
50 => "fifty",
60 => "sixty",
70 => "seventy",
80 => "eighty",
90 => "ninety",
}
attr_reader :int, :parts
def initialize(int)
@int = int
@parts = int.to_s.split('').reverse.map(&:to_i)
end
def thousands
"#{NUMBER_TO_STRING[parts[3]]} thousand" if parts.length > 3
end
def hundreds
"#{NUMBER_TO_STRING[parts[2]]} hundred" if (parts.length > 2 && parts[2] != 0)
end
def tens
tens = parts[1] * 10
units = parts[0]
if ((tens + units) > 10 && (tens + units) < 20)
return NUMBER_TO_STRING[tens + units] if NUMBER_TO_STRING.has_key?(tens + units)
end
NUMBER_TO_STRING[tens] if parts.length > 1
end
def units
tens = parts[1] * 10
units = parts[0]
NUMBER_TO_STRING[parts[0]] unless ((tens + units) > 10 && (tens + units) < 20)
end
def to_s
return NUMBER_TO_STRING[int] if NUMBER_TO_STRING.has_key?(int)
"#{thousands} #{hundreds} #{tens} #{units}".strip.gsub(/\s+/, " ")
end
end
end
require 'rspec'
require 'numberlettercounts'
describe NumberLetterCounts do
describe ".calc" do
it 'should return 19 for 1 - 5' do
described_class.calc(1, 5).should eq 19
end
it 'should return 74 for 1 - 15' do
described_class.calc(1, 15).should eq 74
end
it 'should return 21098 for 1 - 1000' do
described_class.calc(1, 1000).should eq 21098
end
end
describe ".number_to_string" do
it 'should return "twenty three" for 23' do
described_class.number_to_string(23).should eq "twenty three"
end
it 'should return "seventy five" for 75' do
described_class.number_to_string(75).should eq "seventy five"
end
it 'should return "one hundred fifty five" for 155' do
described_class.number_to_string(155).should eq "one hundred fifty five"
end
it 'should return "one thousand one hundred fifty five" for 1155' do
described_class.number_to_string(1155).should eq "one thousand one hundred fifty five"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment