# Count and Say (#138)

**URL:** <https://www.ruby-forum.com/t/count-and-say-138/114371>\
**Category:** Ruby\
**Created:** [September 11, 2007, 10:53pm UTC](https://www.ruby-forum.com/t/count-and-say-138/114371 "2007-09-11T22:53:29Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ivan\_Zdravkovic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/5fc32e/32.png) [@Ivan\_Zdravkovic](https://www.ruby-forum.com/u/Ivan_Zdravkovic)\
**Post date:** [September 11, 2007, 10:53pm UTC](https://www.ruby-forum.com/t/count-and-say-138/114371/1 "2007-09-11T22:53:29Z")

</div>

Here is my shot.

Best to you all,  
Izi

-------------------- Cut here  
require ‘test/unit’

# Convert a number [0…999] to how it should be written in English.

class NumberToEnglish  
def initialize  
@ones = [‘zero’, ‘one’, ‘two’, ‘three’, ‘four’, ‘five’, ‘six’,  
‘seven’, ‘eight’, ‘nine’]  
@tens\_10\_to\_19 = [‘ten’, ‘eleven’, ‘twelve’, ‘thirteen’,  
‘fourteen’, ‘fifteen’, ‘sixteen’, ‘seventeen’, ‘eighteen’, ‘nineteen’]  
@tens\_20\_to\_99 = [‘twenty’, ‘thirty’, ‘forty’, ‘fifty’, ‘sixty’,  
‘seventy’, ‘eighty’, ‘ninety’]  
@hundered = ‘hundered’  
end

def english\_0\_to\_9 number  
return @ones[number]  
end

def english\_10\_to\_19 number  
return @tens\_10\_to\_19[number - 10]  
end

def english\_0\_to\_19 number  
return english\_0\_to\_9(number) if number \< 10  
english\_10\_to\_19 number  
end

def english\_20\_to\_99 number  
ones\_part = number % 10  
tens\_part = number / 10 - 2  
head = @tens\_20\_to\_99[tens\_part]  
return head if ones\_part == 0  
head + ‘-’ + english\_0\_to\_9(ones\_part)  
end

def english\_0\_to\_99 number  
return english\_0\_to\_19(number) if number \< 20  
english\_20\_to\_99 number  
end

def english\_100\_to\_999 number  
hundereds\_part = number / 100  
rest\_part = number % 100  
head = @ones[hundereds\_part] + ’ ’ + @hundered  
return head if rest\_part == 0  
head + ’ and ’ + english\_0\_to\_99(number % 100)  
end

def english\_0\_to\_999 number  
return english\_0\_to\_99(number) if number \< 100  
english\_100\_to\_999 number  
end

def english number  
english\_0\_to\_999(number)  
end  
end

class NumberToEnglishTest \< Test::Unit::TestCase  
def setup  
@numberToEnglish = NumberToEnglish.new  
end

def test\_1  
assert\_equal(‘zero’, @numberToEnglish.english(0))  
assert\_equal(‘one’, @numberToEnglish.english(1))  
assert\_equal(‘nine’, @numberToEnglish.english(9))  
assert\_equal(‘ten’, @numberToEnglish.english(10))  
assert\_equal(‘seventeen’, @numberToEnglish.english(17))  
assert\_equal(‘twenty’, @numberToEnglish.english(20))  
assert\_equal(‘fifty-seven’, @numberToEnglish.english(57))  
assert\_equal(‘ninety-nine’, @numberToEnglish.english(99))  
assert\_equal(‘one hundered’, @numberToEnglish.english(100))  
assert\_equal(‘one hundered and ninety-four’,  
@numberToEnglish.english(194))  
assert\_equal(‘two hundered’, @numberToEnglish.english(200))  
assert\_equal(‘two hundered and one’, @numberToEnglish.english(201))  
assert\_equal(‘three hundered and ninety-two’,  
@numberToEnglish.english(392))  
assert\_equal(‘five hundered and twenty-three’,  
@numberToEnglish.english(523))  
assert\_equal(‘seven hundered and seventy-seven’,  
@numberToEnglish.english(777))  
assert\_equal(‘eight hundered and forty-four’,  
@numberToEnglish.english(844))  
assert\_equal(‘nine hundered and forty-three’,  
@numberToEnglish.english(943))  
end  
end

# My (hopefully right) solution of Ruby Q. 138.

class RQ138  
def initialize  
@numberToEnglish = NumberToEnglish.new  
end

def say\_it counts  
str = ‘’  
counts.sort.each do |k, v|  
str += @numberToEnglish.english(v) + ’ ’ + k + ’ ’  
end  
str.chomp  
end

def unwind str  
only\_letters = str.gsub /[^a-z]/, ‘’  
sorted\_str = only\_letters.split(’’).sort  
counts = {}  
sorted\_str.each do |char|  
if counts[char] == nil  
counts[char] = 1  
else  
counts[char] += 1  
end  
end  
say\_it counts  
end

def find\_seq str  
seq = [str]  
1.upto 10000 do  
unwound = unwind seq[seq.length - 1]  
index = seq.index(unwound)  
seq \<\< unwound  
return [seq.length + 1, seq.length - index, seq] if index != nil  
end  
nil # Give up…  
end  
end

class RQ138Test \< Test::Unit::TestCase  
def setup  
@rq138 = RQ138.new  
end

def test\_1  
# WARNING: These are not real tests, since I didn’t validate the  
results.  
assert\_equal [609, 430], @rq138.find\_seq(‘LOOK AND  
SAY’.downcase)[0…1]  
assert\_equal [404, 67], @rq138.find\_seq(‘A’.downcase)[0…1] # No  
letter A in numbers 0 - 9.  
assert\_equal [404, 67], @rq138.find\_seq(‘B’.downcase)[0…1]  
assert\_equal [519, 317], @rq138.find\_seq(‘E’.downcase)[0…1]  
assert\_equal [152, 76], @rq138.find\_seq(‘ROMANCE’.downcase)[0…1] #  
Romance is very short,  
assert\_equal [482, 317], @rq138.find\_seq(‘LOVE’.downcase)[0…1] #  
proof that love can last extremely long,  
assert\_equal [92, 46], @rq138.find\_seq(‘LINUX’.downcase)[0…1] #  
Linux is very fast,  
assert\_equal [783, 95], @rq138.find\_seq(‘RUBY’.downcase)[0…1] #  
while Ruby stands very high.  
assert\_equal [693, 160], @rq138.find\_seq(‘izi\_ttm’)[0…1] # Don’t  
know what I should say about myself,  
assert\_equal [266, 160], @rq138.find\_seq(‘Nikola  
Tesla’.downcase)[0…1] # but I sure have at least something in common  
with Nikola Tesla. 🙂  
end  
end  
-------------------- Cut here
