------art_14041_16440062.1152656407096
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

require "integer"

class Pangrams
  TIMES  0000
  def pos_add(str, arr26)
    (0...str.length).each do |i|
      next if (str[i]< "a"[0])||(str[i]>"z"[0])
      arr26[str[i]-"a"[0]]+    end
    arr26
  end

  def initialize
    @cardinals  rray.new(50) {|i| i.to_i.to_english }
    @ref_array  ]
    @cardinals.each do |num_str|
      pos_vec  rray.new(26, 0)
      pos_vec  elf.pos_add(num_str, pos_vec)
      pos_vec["s"[0]-"a"[0]] +  unless num_str "one"
      @ref_array << pos_vec
    end
  end

  def do_pangram
    @start_str  This is Nasir's pangram and the count is "
    @start_str_cnt_arr  rray.new(26, 0)
    @start_str_cnt_arr  elf.pos_add(@start_str, @start_str_cnt_arr)
    @char_cnt_arr  rray.new(26, 0)
    #@nchar_cnt_arr  rray.new(26, 0)
    srand
    #0.upto(25) {|x| @char_cnt_arr[x]
nd(@cardinals.length) } #init
    loop do
      0.upto(25) {|x| @char_cnt_arr[x]
nd(@cardinals.length) } #init
      TIMES.times do
        val  rue
        0.upto(25) do |idx|
         t  elf.evaluate_at(idx)
         val && 
        end
        if val
          puts "Solution found!"
          puts print(@start_str, @char_cnt_arr)
          exit
        end
      end
      puts "#{TIMES} mark"
      0.upto(25) do |idx|
         puts "At #{idx} current@char_cnt_arr[idx]}, actual
self.count_char_at(idx)}"
      end
      puts "-----------------------------------"
    end
  end # do_pangram


  def evaluate_at(idx)
    current_cnt  char_cnt_arr[idx]
    actual_cnt  elf.count_char_at(idx)
    ret  rue
    if current_cnt ! ctual_cnt
      #printf("*")
      v1  urrent_cnt - ((current_cnt-actual_cnt)*rand).round
      v2  urrent_cnt - ((current_cnt-actual_cnt)*rand).round
      if actual_cnt > current_cnt
        @char_cnt_arr[idx]  v1,v2].max
      else
        @char_cnt_arr[idx]  v1,v2].min
      end
      ret  alse


    end
    ret
  end

  # index in char_cnt_arr, 'a' is 0 'z' is 25
  # Gives the current count of the character in the string
  def count_char_at(i)
    count  @start_str_cnt_arr[i] # assume only orig string for start
    count +                      # always 1a, 1b etc
    @char_cnt_arr.each do |cnt|
      count + @ref_array[cnt])[i] #ref_arr[0] is zero
    end
    count
  end



  def print(str, arr)
    my_str  tr
    fmts  %s %c, "
    fmtp  %s %c's, "
    arr.each_with_index do |elm, i|
      if elm
        my_str << sprintf(fmts, @cardinals[elm], 97+i)
      else
        my_str << sprintf(fmtp, @cardinals[elm], 97+i)
      end
    end
    yield my_str if block_given?
    my_str
  end


end  #class

p  angrams.new
p.do_pangram

in
This re-uses quiz #25's solution by Glenn PArker.
The algorithm looks simple enough but there is something wrong with this
implementation that it does not converge, sometimes never.
Going by the Pangram defintion I am just comparing the current (guessed)
with actual (counted) and if different replacing the current with a random
number between current and actual (inclusive)  with a bias towards actual.
This is what I understood it to be, but there is obviously something that I
am missing as this is terribly inefficient. (Mostly going into orbits)
You may notice that I have tried both changing current value one at a time
and also accumulating changes in @nchar_cnt_arr and changing in one go. The
convergence has been elusive in either case.
One way for me is to start looking at other solutions (which I will
certainly do), but it would be a great help if someone points me towards a
flaw in this.
Also since I am new to Ruby, any general suggestion in Ruby usage will be
greatly appreciated.

On a side note, has anyone tried any other algorithm besides RR?
Specifically has anyone tried simulated annealing or a variation? I tried
unsuccesfully (again) using SA yesterday.

ίΕ
--
Nasir Khan

------art_14041_16440062.1152656407096--