tree5.rb

#!/usr/bin/ruby1.8 def fwd(x, b)     fsm = $fsm              s, i, o = x     s = 0 if (s.nil?)              return nil if (fsm[s][b].nil?)         s2, i2, o2 = fsm[s][b]         while (!fsm[s2][0].nil?)                 s2, i3, o3 = fsm[s2][0]                 o2 += o3         end         y = [s2, i + i2, o + o2] #       p([x, b.to_s + '=>', y])         return y end def fsm()         fsm = {}         File.open('fsm3nb.txt').each \         {                 |ln|                 l = ln.split                 l[0] = l[0].to_i                 fsm[l[0]] = [] if (fsm[l[0]].nil?)                 next if (l.size == 1)                 l[1] = l[1].to_i                 l[3] = '' if (l[3] == '0')                 fsm[l[0]][l[2].to_i] = l[1..3]         }         return fsm end def prefix(s, x)          y = x[0]     z = x[1]     return [s + y,  [s + z[0]] + z[1..-1]] end def middle(x)          return (x.split('').size.even?) end def bin2(l)         l = l.dup         s = ''         while (!l.empty?)                 l.shift         return s + '.' if (l.empty?)         s << (l.shift - 1).to_s         end         return s end def fmt(x)     return '' if (x.nil?)     return ([bin2(x[0].split('').map { |x| x.to_i}.reverse)] + x[1]).inspect end      def adv(x)     z = x[1]     l1 = []     if (middle(x[0])) then              l1 << prefix('11', x)         l1 << prefix('21', x)         l1 << prefix('2', x)         return l1 if (z[0].empty?)     end #    return l1          z2 = z.dup     j = 0     while (z[j].empty?)         j += 2     end #    p([j, x])          s = z[j].dup     i = s[-1].to_i     s[-1] = ''          l = [z[j + 1], '', '']     l = fwd(l, i)          return [] if (l.nil?)     s2 = z[j + 2]     s2 = '' if (s2.nil?)     s2 = l[2].reverse + s2          z2[j] = s     z2[j + 1] = l[0]     z2[j + 2] = s2 if (!s2.empty?)     x2 = [x[0], z2]      #    puts(fmt(x) + "\t=>\t" + fmt(x2))          l1 << x2          return l1      end def adv2(x)     l = adv(x) #    puts(fmt(x) + "\t=>\t")     l.each \     {         |x| #        puts(fmt(x))     }     return l end def seen(x)     y = x[1].dup     z = y.dup     while (y[0].empty? && y[1] == 30)         y.shift         y.shift     end                    if ($seen.member?(y)) then #        puts("xxx")         return true     end     $seen[y] = nil     return false      end def rank1(x)          l = x[1].dup     c = 0     l2 = []     while (!l.empty?)         l2 << l.shift.size         c += l2[-1]         l.shift     end          return [{true=>1,false=>0}[middle(x[0])], x[0].size, x[1].size, c, x[0]] end def rank2(x)     return [x[0].size, x[0]] end def rank3(x)          l = x[1].dup     c = 0     l2 = []     while (!l.empty?)         l2 << l.shift.size         c += l2[-1]         l.shift     end          return [{true=>1,false=>0}[middle(x[0])], c, x[0]]      end def fmt2(x)     p(x)     return fmt(x[0]) + x[1].inspect      end def rank(x)     return rank3(x)      end $fsm = fsm() $seen = {} l = [['', ['', 0]]] n = 0 loop \ {     n += 1          puts     i = (0...l.size).to_a.sort_by { |x| rank(l[x]) }     p([n, l.size, $seen.size, i[0]])          i.each { |x| printf("%-30s %s\n", rank(l[x]), fmt(l[x])) }          x = l.delete_at(i[0]) #    p([rank(x), x])     l2 = adv2(x)     l2.each \     {         |y|         next if seen(y)              l << y     } } 

Leave a comment