On 9/6/07, Ruby Quiz <james / grayproductions.net> wrote:
> Over on rec.puzzles, Eric A. proposed a variant in which the letters of a
> sentence are grouped, then "counted aloud", omitting the "s"s for the plural
> form. Thus, seeding the sequence with "LOOK AND SAY", we get:
>
>        0. LOOK AND SAY
>        1. TWO A ONE D ONE K ONE L ONE N TWO O ONE S ONE Y
>        2. ONE A ONE D SIX E ONE K ONE L SEVEN N NINE O ONE S TWO T TWO W ONE Y
>        3. ONE A ONE D TEN E TWO I ONE K ONE L TEN N NINE O THREE S THREE T ONE V
>           THREE W ONE X ONE Y
>
> and so on. (Note the difference between this and the L&S sequence--the letters
> are counted rather than read in order). Eric wants to know when the sequence
> enters a cycle, and how long that cycle is. Well?
>


My solution follows.  I rolled my own integer to word routine.  The
shortest cycle I found starts with letter 'Y':
C:\code\quiz>looksay2.rb y
Y

After 50 iterations, repeated pattern 48:
SIXTEEN E SIX F TWO G THREE H FIVE I TWO L NINE N NINE O SIX R FOUR S
FOUR T FIVE U FIVE V TWO W TWO X ONE Y
Loop length = 2


-Adam

---looksay2.rb---

class Integer
  GROUPS =%W{ THOUSAND MILLION BILLION TRILLION QUADRILLION
QUINTILLION SEXILLION SEPTILLION OCTILLION NONILLION}.unshift nil
  DIGITS = %W{ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE}.unshift nil
  TEENS = %W{TEN ELEVEN TWELVE THIRTEEN FOURTEEN FIFTEEN SIXTEEN
SEVENTEEN EIGHTEEN NINETEEN}
  TENS = %W{TEN TWENTY THIRTY FOURTY FIFTY SIXTY SEVENTY EIGHTY
NINETY}.unshift nil
  def to_w
    return @word if @word
    p "making word for #{self}" if $DEBUG
    digits = to_s.split('').reverse.map{|c|c.to_i}
    return @word = "DECILLIONS" if digits.size > 33
    phrase,group = [],0
    until digits.empty?
      phrase << GROUPS[group]
      d = digits.slice!(0,3)
      d[1]||=0
      if d[1] == 1
        phrase << TEENS[d[0]]
      else
        phrase << DIGITS[d[0]] << TENS[d[1]]
      end
      phrase << "HUNDRED" << DIGITS[d[2]]  if (d[2] and d[2]!=0)
      phrase.pop if (phrase.compact! and phrase[-1] ==  GROUPS[group])
      group+=1
    end
    @word = phrase.reverse.join ' '
  end
end


if __FILE__ == $0

phrase = ARGV[0]||"LOOK AND SAY"
print = ARGV[1] == 'p'
results=[];
h=Hash.new(0)
i=0
str = phrase.upcase
puts str
until (m = results.index str)
  print "#{i}: ", str, "\n" if print
  results<< str
  str.split('').each{|c| h[c]+=1}
  h.delete(' ')
  str = h.to_a.sort.map{|c,n| [n.to_w,c] }.join " "
  h.clear
  i+=1
end
puts "\nAfter #{i} iterations, repeated pattern #{m}: "
puts str
puts "Loop length = #{i-m}"
end