Simon Kröger
7/10/2006 6:37:00 PM
>> Huh. I must say that when I saw your program, it wasn't at all what I
>> expected - namely, you are changing all 26 letters at once, and then
>> recalculating. I had assumed you were doing one letter at a time,
>> which I found to be much, much faster than doing all 26 at once.
>
> Ok, I will post my other version as soon as I'm home again.
Here is the second version (which was my first version):
--------------------------------------------------------------------
require 'narray'
class NArray; include Enumerable; end
srand(1)
NUMS = %w(no one two three four five six seven eight nine ten eleven) +
%w(twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen)
TENS = [nil] + %w(teen twenty thirty forty fifty sixty seventy eighty ninety)
class Fixnum
def to_english
return NUMS[self] if self < 20
return TENS[self / 10] if (self % 10).zero?
TENS[self / 10] + '-' + NUMS[self % 10]
end
end
class String
def to_na
count = NArray.byte(26)
each_byte do |b|
count[b - ?a] += 1 if b >= ?a and b <= ?z
count[b - ?A] += 1 if b >= ?A and b <= ?Z
end
count
end
end
text = "This is a pangram from simon, it contains "
number = (0..99).map{|i| i.to_english.to_na + (i > 1 ? 's' : '').to_na}
guess = NArray.byte(26).fill!(1)
real = guess + text.to_na + 'and'.to_na + (number[1] * 26)
i, r, g, changed = nil, nil, nil, true
while changed do
changed = false
26.times do |i|
g = guess[i]
r = real[i]
if g != r
real.sbt! number[g]
guess[i] = g = (g < r ? g : r) + rand((g - r).abs + 1)
real.add! number[g]
changed = true
end
end
end
s = guess.zip([*(' a'..' z')]).map{|g, l| g.to_english + l + (g>1 ? "'s":"")}
result = text + s[0..-2].join(', ') + ' and ' + s.last + '.'
puts result
puts(result.to_na == guess)
--------------------------------------------------------------------
It's quite similar except the loop.
cheers
Simon