From: Robert Dober Date: 2007-03-11T22:55:10+09:00 Subject: Re: [QUIZ] SimFrost (#117) ------=_Part_20344_4369595.1173621305310 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline Code's slow :( post's fast ;) hopefully I find some time to profile and optimise the whole thing. run.rb is the shell cmdline frontend torus.rb is the freezer ascii.rb and ppm.rb are two output plugins. actually the output of the follwoing is nice already rubr run.rb -f ascii 80 80 0.5 && \ for i in output/run-80-80.000000*.txt ; do clear; cat $i; sleep 1; done GQView shows the ppm files nicely too and I guess lot's of other viewers do but I did not mange to create movies on Linux yet, any hints would be appreciated. And before I forget YET ANOTHER GREAT RUBY QUIZ :)) 534/35 > cat run.rb ------------------------- # vim: sw=2 sts=2 nu tw=0 expandtab: # require 'fileutils' require 'torus' def usage msg = nil $stderr.puts msg if msg $stderr.puts <<-EOS usage: #{$0} [options] height width vapor_probability options and their defaults -s|--start /2@/2 where to put the initial freezer please use Smalltalk syntax here -n|--name run-- name of the output file -v|--vapor 255/0/255 rgb value for PPM O use strings for ASCII -0|--vacuum 0/0/0 idem -i|--ice 255/255/255 idem * -f|--format ppm ppm or ascii are supported write your own plugins ;) have fun EOS exit -1 end @start = @name = nil @vapor = nil @vacuum = nil @ice = nil @format = "ppm" options = { /^-f|^--format/ => :format, /^-s|^--start/ => :start, /^-n|^--name/ => :name, /^-v|^--vapor/ => :vapor, /^-0|^--vacuum/ => :vacuum, /^-i|^--ice/ => :ice } loop do break if ARGV.empty? break if ARGV.first == "--" break unless /^-/ === ARGV.first illegal_option = true options.each do | opt_reg, opt_sym | if opt_reg === ARGV.first then usage "Missing argument for option #{ARGV}" if ARGV.length < 2 instance_variable_set( "@#{opt_sym}", ARGV[1] ) ARGV.slice!( 0, 2 ) illegal_option = false end end usage ARGV.first if illegal_option end usage ARGV.join(", ") unless ARGV.size == 3 require @format rescue usage begin mkdir( "output" ) unless File.directory?( "output" ) rescue $stderr.puts 'Cannot create output directory "output"' usage end t = Torus( *(ARGV << @start) ) t.name = @name || "run-#{ARGV[0..1].join("-")}" t.formatter = Formatter.new( ICE => @ice, VAPOR => @vapor, VACUUM => @vacuum ) t.start_sim ==================================================== 535/36 > cat torus.rb -------------------------- # vim: sw=2 sts=2 nu tw=0 expandtab nowrap: # # ICE = Class.new VAPOR = Class.new VACUUM = Class.new ############################################################### # # a small reference to Python ;) # ############################################################### def Torus( rows, cols, vapors, start = nil ) Torus_.new( rows.to_i, cols.to_i, vapors.to_f, start ) end class Torus_ ############################################################### # # Torus_ # ############################################################### attr_reader :lines, :columns attr_reader :generation attr_accessor :formatter, :name def initialize rows, cols, vapors, start @lines = rows @columns = cols @vapors = vapors @generation = 0 if start then @start = start.split("@").map{|e| e.to_i} else @start ||= [ rows/2, cols /2 ] end @nhoods = [] # we will store neighborhoods identified by # their upper left corner index, odd is for even generations # and even is for odd generations, which might seem odd. reset_values set_vapors end def [] line, col=nil return @values[line] unless col @values[line][col] end # def [](line, col=nil) def []= line, col, val @values[line][col] = val end def each_cell (1..@lines).each do | line | (1..@columns).each do | column | yield @values[line-1][column-1], line-1, column-1 end # (0..@columns).each do end # (0..@lines).each do end # def each_cell &blk def each_line @values.each{ |line| yield line } end def each_nbh r = c = @generation % 2 loop do yield @nhoods[ linear_idx( r, c ) ] ||= Neighborhood.new( self, r, r.succ % @lines, c, c.succ % @columns ) c += 2 r += 2 unless c < @columns return unless r < @lines c %= @columns r %= @lines end end def set_from_str str @values = [] str.strip.split("\n").each do | line_str | @values << [] line_str.each_byte do | char | @values.last << case char.chr when ICE.to_s ICE when VACUUM.to_s VACUUM when VAPOR.to_s VAPOR end end end end def start_sim until no_more_vapor? do tick write end end # def start_sim def tick puts "Simulation #{@name} generation #{@generation}:" @generation += 1 each_nbh do | nbh | nbh.recalc end end private def no_more_vapor? ! @values.any?{ |line| line.any?{ |v| v == VAPOR } } end def reset_values @values = Array.new(@lines){ Array.new(@columns){ VACUUM } } end def set_vapors total = @lines * @columns v = ( @vapors * (total-1) ).to_i x = [*0..total-2] at = [] v.times do at << x.delete_at( rand(x.size) ) end at.each do | index | l,c = matrix_idx index @values[l][c] = VAPOR end @values[@lines-1][@columns-1] = @values[@start.first][@start.last] @values[@start.first][@start.last] = ICE end # def set_vapors def linear_idx r, c r * @columns + c end def matrix_idx l return l / @columns, l % @columns end def write @formatter.to_file self, "output/#{@name}.%08d" % @generation end # def write end # class Torus_ ############################################################### # # Neighborhood is implementing a 2x2 window to any object # that responds to #[]n,m and #[]=n,m,value # It implements the operation of rotation. # ############################################################### class Neighborhood < Struct.new( :torus, :top, :bottom, :left, :right ) include Enumerable # Neighborhood gives us the following indexed view to the underlying # torus # +---+---+ +-----------+-----------+ # | 0 | 1 | | @top,@lft | @top,@rgt | # +---+---+ +-----------+-----------+ # | 3 | 2 | | @bot,@lft | @bot,@rgt | # +---+---+ +-----------+-----------+ # # The Name and the Indexer implement that mapping Names = [ %w{ top left }, %w{ top right }, %w{ bottom right }, %w{ bottom left } ] def initialize *args super *args end alias_method :__access__, :[] # Needed b/c/o the limited access # abilities of Struct def [] n __access__("torus")[ *resolve_idx( n ) ] end def []= n, val __access__("torus")[ *resolve_idx( n ) ] = val end def each 4.times do | idx | yield self[idx] end end def recalc if any?{|v| v == ICE} then 4.times do | idx | self[ idx ] = ICE if self[ idx ] == VAPOR end else rotate( rand(2) ) end end def rotate dir x = self[0] 3.times do | n | self[ n + 2*dir*n ] = self[ n + 1 + dir*2*n.succ ] end # 3.times do self[ 3 + 2 * dir ] = x end # def rotate dir private def resolve_idx n [ __access__( Names[ n % 4 ].first ), __access__( Names[ n % 4 ].last) ] end # def resolv_idx end # class Neighborhood ================================================== 538/39 > cat ascii.rb -------------------------- # vim: sw=2 sts=2 nu tw=0 expandtab nowrap: class Formatter @@default = { ICE => "*", VAPOR => "0", VACUUM => " " } def initialize chars={} @chars = Hash[ *chars.to_a.map{ |(k,v)| [k, v || @@default[k] ] }.flatten ] end # def initialize colors={} def to_file( source, file, comment = nil ) File.open( "#{file}.txt", "w" ) do | f | source.each_line{ |line| line.each do | cell | f.print @chars[cell] end f.puts } end end end ================================================== 539/40 > cat ppm.rb -------------------------- # vim: sw=2 sts=2 nu tw=0 expandtab nowrap: class Formatter @@default = { ICE => "255/255/255", VAPOR => "255/0/255", VACUUM => "0/0/0" } def initialize colors={} @colors = {} colors.each do | element, color | color ||= @@default[element] @colors[ element ] = " " << color.gsub("/", " ") << " " end # colors.each do end # def initialize colors={} def to_file( source, file, comment = nil ) comment ||= file File.open( "#{file}.ppm", "w" ) do | f | f.puts "P3 #{source.columns} #{source.lines} 255" f.puts "#" f.puts "# #{comment}" f.puts "#" source.each_line{ |line| count = 0 line.each do | cell | s = @colors[cell] if count + s.size > 70 then f.puts count = 0 end count += s.size f.print s end f.puts unless count.zero? } end end end ============================================ ------=_Part_20344_4369595.1173621305310 Content-Type: application/x-ruby; name="ascii.rb" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="ascii.rb" X-Attachment-Id: f_ez5idwji IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWIgbm93cmFwOgoKCmNsYXNzIEZvcm1h dHRlcgoKICBAQGRlZmF1bHQgPSB7IElDRSA9PiAiKiIsCiAgICAgICAgICAgICAgICBWQVBPUiA9 PiAiMCIsCiAgICAgICAgICAgICAgICBWQUNVVU0gPT4gIiAiIAogIH0KICBkZWYgaW5pdGlhbGl6 ZSBjaGFycz17fQogICAgQGNoYXJzID0gCiAgICAgIEhhc2hbICpjaGFycy50b19hLm1hcHsgfChr LHYpfCBbaywgdiB8fCBAQGRlZmF1bHRba10gXSB9LmZsYXR0ZW4gXQogIGVuZCAjIGRlZiBpbml0 aWFsaXplIGNvbG9ycz17fQoKICBkZWYgdG9fZmlsZSggc291cmNlLCBmaWxlLCBjb21tZW50ID0g bmlsICkKICAgIEZpbGUub3BlbiggIiN7ZmlsZX0udHh0IiwgInciICkgZG8KICAgICAgfCBmIHwK ICAgICAgc291cmNlLmVhY2hfbGluZXsKICAgICAgICB8bGluZXwKICAgICAgICBsaW5lLmVhY2gg ZG8KICAgICAgICAgIHwgY2VsbCB8CiAgICAgICAgICBmLnByaW50IEBjaGFyc1tjZWxsXQogICAg ICAgIGVuZAogICAgICAgIGYucHV0cwogICAgICB9CiAgICBlbmQKICBlbmQKICAKZW5kCg== ------=_Part_20344_4369595.1173621305310 Content-Type: application/x-ruby; name="ppm.rb" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="ppm.rb" X-Attachment-Id: f_ez5ief6f IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWIgbm93cmFwOgoKCmNsYXNzIEZvcm1h dHRlcgoKICBAQGRlZmF1bHQgPSB7IElDRSA9PiAiMjU1LzI1NS8yNTUiLAogICAgICAgICAgICAg ICAgVkFQT1IgPT4gIjI1NS8wLzI1NSIsCiAgICAgICAgICAgICAgICBWQUNVVU0gPT4gIjAvMC8w IiAKICB9CgogIGRlZiBpbml0aWFsaXplIGNvbG9ycz17fQogICAgQGNvbG9ycyA9IHt9CiAgICBj b2xvcnMuZWFjaCBkbwogICAgICB8IGVsZW1lbnQsIGNvbG9yIHwKICAgICAgY29sb3IgfHw9IEBA ZGVmYXVsdFtlbGVtZW50XQogICAgICBAY29sb3JzWyBlbGVtZW50IF0gPSAiICIgPDwgY29sb3Iu Z3N1YigiLyIsICIgIikgPDwgIiAiCiAgICBlbmQgIyBjb2xvcnMuZWFjaCBkbwogIGVuZCAjIGRl ZiBpbml0aWFsaXplIGNvbG9ycz17fQoKICBkZWYgdG9fZmlsZSggc291cmNlLCBmaWxlLCBjb21t ZW50ID0gbmlsICkKICAgIGNvbW1lbnQgfHw9IGZpbGUKICAgIEZpbGUub3BlbiggIiN7ZmlsZX0u cHBtIiwgInciICkgZG8KICAgICAgfCBmIHwKICAgICAgZi5wdXRzICJQMyAje3NvdXJjZS5jb2x1 bW5zfSAje3NvdXJjZS5saW5lc30gMjU1IgogICAgICBmLnB1dHMgIiMiCiAgICAgIGYucHV0cyAi IyAje2NvbW1lbnR9IgogICAgICBmLnB1dHMgIiMiCiAgICAgIHNvdXJjZS5lYWNoX2xpbmV7CiAg ICAgICAgfGxpbmV8CiAgICAgICAgY291bnQgPSAwCiAgICAgICAgbGluZS5lYWNoIGRvCiAgICAg ICAgICB8IGNlbGwgfAogICAgICAgICAgcyA9IEBjb2xvcnNbY2VsbF0KICAgICAgICAgIGlmIGNv dW50ICsgcy5zaXplID4gNzAgdGhlbgogICAgICAgICAgICBmLnB1dHMgCiAgICAgICAgICAgIGNv dW50ID0gMAogICAgICAgICAgZW5kCiAgICAgICAgICBjb3VudCArPSBzLnNpemUKICAgICAgICAg IGYucHJpbnQgcwogICAgICAgIGVuZAogICAgICAgIGYucHV0cyB1bmxlc3MgY291bnQuemVybz8K ICAgICAgfQogICAgZW5kCiAgZW5kCiAgCmVuZAo= ------=_Part_20344_4369595.1173621305310 Content-Type: application/x-ruby; name="run.rb" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="run.rb" X-Attachment-Id: f_ez5ielfk IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWI6DQojDQpyZXF1aXJlICdmaWxldXRp bHMnDQpyZXF1aXJlICd0b3J1cycNCg0KZGVmIHVzYWdlIG1zZyA9IG5pbA0KICAkc3RkZXJyLnB1 dHMgbXNnIGlmIG1zZw0KICAkc3RkZXJyLnB1dHMgPDwtRU9TDQogIHVzYWdlOg0KICAjeyQwfSBb b3B0aW9uc10gaGVpZ2h0IHdpZHRoIHZhcG9yX3Byb2JhYmlsaXR5DQoNCiAgb3B0aW9ucyBhbmQg dGhlaXIgZGVmYXVsdHMNCiAgLXN8LS1zdGFydCA8aGVpZ2h0Pi8yQDx3aWR0aD4vMiAgICAgIHdo ZXJlIHRvIHB1dCB0aGUgaW5pdGlhbCBmcmVlemVyDQogICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBwbGVhc2UgdXNlIFNtYWxsdGFsayBzeW50YXggaGVyZQ0KICAtbnwtLW5h bWUgICBydW4tPGhlaWdodD4tPHdpZHRoPiAgICAgbmFtZSBvZiB0aGUgb3V0cHV0IGZpbGUNCiAg LXZ8LS12YXBvciAgMjU1LzAvMjU1ICAgICAgICAgICAgICAgIHJnYiB2YWx1ZSBmb3IgUFBNDQog ICAgICAgICAgICAgIE8gICAgICAgICAgICAgICAgICAgICAgICB1c2Ugc3RyaW5ncyBmb3IgQVND SUkNCiAgLTB8LS12YWN1dW0gMC8wLzAgICAgICAgICAgICAgICAgICAgIGlkZW0NCiAgICAgICAg ICAgICAgPHNwYWNlPg0KICAtaXwtLWljZSAgICAyNTUvMjU1LzI1NSAgICAgICAgICAgICAgaWRl bQ0KICAgICAgICAgICAgICAqDQogIC1mfC0tZm9ybWF0IHBwbSAgICAgICAgICAgICAgICAgICAg ICBwcG0gb3IgYXNjaWkgYXJlIHN1cHBvcnRlZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgd3JpdGUgeW91ciBvd24gcGx1Z2lucyA7KQ0KDQogIGhhdmUgZnVuDQogIEVP Uw0KICBleGl0IC0xDQplbmQNCg0KQHN0YXJ0ID0gQG5hbWUgPSBuaWwNCkB2YXBvciA9IG5pbA0K QHZhY3V1bSA9IG5pbA0KQGljZSAgICA9IG5pbA0KQGZvcm1hdCA9ICJwcG0iIA0Kb3B0aW9ucyA9 IHsgL14tZnxeLS1mb3JtYXQvID0+IDpmb3JtYXQsDQogICAgICAgICAgICAvXi1zfF4tLXN0YXJ0 LyAgPT4gOnN0YXJ0LA0KICAgICAgICAgICAgL14tbnxeLS1uYW1lLyAgID0+IDpuYW1lLA0KICAg ICAgICAgICAgL14tdnxeLS12YXBvci8gID0+IDp2YXBvciwNCiAgICAgICAgICAgIC9eLTB8Xi0t dmFjdXVtLyA9PiA6dmFjdXVtLA0KICAgICAgICAgICAgL14taXxeLS1pY2UvICAgID0+IDppY2Ug fQ0KbG9vcCBkbw0KICBicmVhayBpZiBBUkdWLmVtcHR5Pw0KICBicmVhayBpZiBBUkdWLmZpcnN0 ID09ICItLSINCiAgYnJlYWsgdW5sZXNzIC9eLS8gPT09IEFSR1YuZmlyc3QNCiAgaWxsZWdhbF9v cHRpb24gPSB0cnVlDQogIG9wdGlvbnMuZWFjaCBkbw0KICAgIHwgb3B0X3JlZywgb3B0X3N5bSB8 DQogICAgaWYgb3B0X3JlZyA9PT0gQVJHVi5maXJzdCB0aGVuDQogICAgICB1c2FnZSAiTWlzc2lu ZyBhcmd1bWVudCBmb3Igb3B0aW9uICN7QVJHVn0iIGlmIEFSR1YubGVuZ3RoIDwgMg0KICAgICAg aW5zdGFuY2VfdmFyaWFibGVfc2V0KCAiQCN7b3B0X3N5bX0iLCBBUkdWWzFdICkNCiAgICAgIEFS R1Yuc2xpY2UhKCAwLCAyICkNCiAgICAgIGlsbGVnYWxfb3B0aW9uID0gZmFsc2UNCiAgICBlbmQN CiAgZW5kDQogIHVzYWdlIEFSR1YuZmlyc3QgaWYgaWxsZWdhbF9vcHRpb24gDQplbmQNCnVzYWdl IEFSR1Yuam9pbigiLCAiKSB1bmxlc3MgQVJHVi5zaXplID09IDMNCg0KcmVxdWlyZSBAZm9ybWF0 IHJlc2N1ZSB1c2FnZQ0KDQpiZWdpbg0KICBta2RpciggIm91dHB1dCIgKSB1bmxlc3MgRmlsZS5k aXJlY3Rvcnk/KCAib3V0cHV0IiApIA0KcmVzY3VlIA0KICAkc3RkZXJyLnB1dHMgJ0Nhbm5vdCBj cmVhdGUgb3V0cHV0IGRpcmVjdG9yeSAib3V0cHV0IicNCiAgdXNhZ2UNCmVuZA0KDQp0ID0gVG9y dXMoICooQVJHViA8PCBAc3RhcnQpICkNCnQubmFtZSA9IEBuYW1lIHx8ICJydW4tI3tBUkdWWzAu LjFdLmpvaW4oIi0iKX0iDQp0LmZvcm1hdHRlciA9IEZvcm1hdHRlci5uZXcoIElDRSA9PiBAaWNl LCBWQVBPUiA9PiBAdmFwb3IsIFZBQ1VVTSA9PiBAdmFjdXVtICkNCnQuc3RhcnRfc2ltDQo= ------=_Part_20344_4369595.1173621305310 Content-Type: application/x-ruby; name="torus.rb" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="torus.rb" X-Attachment-Id: f_ez5ieoum IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWIgbm93cmFwOg0KIw0KIw0KDQpJQ0Ug PSBDbGFzcy5uZXcNClZBUE9SID0gQ2xhc3MubmV3DQpWQUNVVU0gPSBDbGFzcy5uZXcNCg0KDQoj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMNCiMNCiMgYSBzbWFsbCByZWZlcmVuY2UgdG8gUHl0aG9uIDspDQojDQojIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCmRl ZiBUb3J1cyggcm93cywgY29scywgdmFwb3JzLCBzdGFydCA9IG5pbCApDQogIFRvcnVzXy5uZXco IHJvd3MudG9faSwgY29scy50b19pLCB2YXBvcnMudG9fZiwgc3RhcnQgKQ0KZW5kDQoNCmNsYXNz IFRvcnVzXw0KDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjDQogICMgICAgVG9ydXNfDQogICMNCiAgIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQog IGF0dHJfcmVhZGVyIDpsaW5lcywgOmNvbHVtbnMNCiAgYXR0cl9yZWFkZXIgOmdlbmVyYXRpb24N CiAgYXR0cl9hY2Nlc3NvciA6Zm9ybWF0dGVyLCA6bmFtZQ0KICBkZWYgaW5pdGlhbGl6ZSByb3dz LCBjb2xzLCB2YXBvcnMsIHN0YXJ0DQogICAgQGxpbmVzID0gcm93cw0KICAgIEBjb2x1bW5zID0g Y29scw0KICAgIEB2YXBvcnMgPSB2YXBvcnMNCiAgICBAZ2VuZXJhdGlvbiA9IDANCiAgICBpZiBz dGFydCB0aGVuDQogICAgICBAc3RhcnQgPSBzdGFydC5zcGxpdCgiQCIpLm1hcHt8ZXwgZS50b19p fQ0KICAgIGVsc2UNCiAgICAgIEBzdGFydCB8fD0gWyByb3dzLzIsIGNvbHMgLzIgXQ0KICAgIGVu ZA0KICAgIEBuaG9vZHMgPSBbXSAgIyB3ZSB3aWxsIHN0b3JlIG5laWdoYm9yaG9vZHMgaWRlbnRp ZmllZCBieQ0KICAgICMgdGhlaXIgdXBwZXIgbGVmdCBjb3JuZXIgaW5kZXgsIG9kZCBpcyBmb3Ig ZXZlbiBnZW5lcmF0aW9ucw0KICAgICMgYW5kIGV2ZW4gaXMgZm9yIG9kZCBnZW5lcmF0aW9ucywg d2hpY2ggbWlnaHQgc2VlbSBvZGQuDQogICAgcmVzZXRfdmFsdWVzDQogICAgc2V0X3ZhcG9ycw0K ICBlbmQNCg0KICBkZWYgW10gbGluZSwgY29sPW5pbA0KICAgIHJldHVybiBAdmFsdWVzW2xpbmVd IHVubGVzcyBjb2wNCiAgICBAdmFsdWVzW2xpbmVdW2NvbF0NCiAgZW5kICMgZGVmIFtdKGxpbmUs IGNvbD1uaWwpDQogIGRlZiBbXT0gbGluZSwgY29sLCB2YWwNCiAgICBAdmFsdWVzW2xpbmVdW2Nv bF0gPSB2YWwNCiAgZW5kDQogIGRlZiBlYWNoX2NlbGwgDQogICAgKDEuLkBsaW5lcykuZWFjaCBk bw0KICAgICAgfCBsaW5lIHwNCiAgICAgICgxLi5AY29sdW1ucykuZWFjaCBkbw0KICAgICAgICB8 IGNvbHVtbiB8DQogICAgICAgIHlpZWxkIEB2YWx1ZXNbbGluZS0xXVtjb2x1bW4tMV0sIGxpbmUt MSwgY29sdW1uLTENCiAgICAgIGVuZCAjICgwLi5AY29sdW1ucykuZWFjaCBkbw0KICAgIGVuZCAj ICgwLi5AbGluZXMpLmVhY2ggZG8NCiAgZW5kICMgZGVmIGVhY2hfY2VsbCAmYmxrDQoNCiAgZGVm IGVhY2hfbGluZQ0KICAgIEB2YWx1ZXMuZWFjaHsgfGxpbmV8IHlpZWxkIGxpbmUgfQ0KICBlbmQN Cg0KICBkZWYgZWFjaF9uYmgNCiAgICByID0gYyA9IEBnZW5lcmF0aW9uICUgMg0KICAgIGxvb3Ag ZG8NCiAgICAgIHlpZWxkIEBuaG9vZHNbIGxpbmVhcl9pZHgoIHIsIGMgKSBdIHx8PSANCiAgICAg ICAgICBOZWlnaGJvcmhvb2QubmV3KCBzZWxmLCByLCByLnN1Y2MgJSBAbGluZXMsIGMsIGMuc3Vj YyAlIEBjb2x1bW5zICkNCiAgICAgIGMgKz0gMg0KICAgICAgciArPSAyIHVubGVzcyBjIDwgQGNv bHVtbnMNCiAgICAgIHJldHVybiB1bmxlc3MgciA8IEBsaW5lcw0KICAgICAgYyAlPSBAY29sdW1u cw0KICAgICAgciAlPSBAbGluZXMNCiAgICBlbmQNCiAgZW5kDQoNCiAgZGVmIHNldF9mcm9tX3N0 ciBzdHINCiAgICBAdmFsdWVzID0gW10NCiAgICBzdHIuc3RyaXAuc3BsaXQoIlxuIikuZWFjaCBk bw0KICAgICAgfCBsaW5lX3N0ciB8DQogICAgICBAdmFsdWVzIDw8IFtdDQogICAgICBsaW5lX3N0 ci5lYWNoX2J5dGUgZG8NCiAgICAgICAgIHwgY2hhciB8DQogICAgICAgICBAdmFsdWVzLmxhc3Qg PDwgY2FzZSBjaGFyLmNocg0KICAgICAgICAgICAgICAgICAgICAgICAgICB3aGVuIElDRS50b19z DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNFDQogICAgICAgICAgICAgICAgICAgICAg ICAgIHdoZW4gVkFDVVVNLnRvX3MNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUNVVU0N CiAgICAgICAgICAgICAgICAgICAgICAgICAgd2hlbiBWQVBPUi50b19zDQogICAgICAgICAgICAg ICAgICAgICAgICAgICAgVkFQT1INCiAgICAgICAgICAgICAgICAgICAgICAgICBlbmQNCg0KICAg ICAgZW5kDQogICAgZW5kDQogIGVuZA0KDQogIGRlZiBzdGFydF9zaW0NCiAgICB1bnRpbCBub19t b3JlX3ZhcG9yPyBkbw0KICAgICAgdGljaw0KICAgICAgd3JpdGUNCiAgICBlbmQNCiAgZW5kICMg ZGVmIHN0YXJ0X3NpbQ0KDQogIGRlZiB0aWNrDQogICAgcHV0cyAiU2ltdWxhdGlvbiAje0BuYW1l fSBnZW5lcmF0aW9uICN7QGdlbmVyYXRpb259OiINCiAgICBAZ2VuZXJhdGlvbiArPSAxDQogICAg ZWFjaF9uYmggZG8NCiAgICAgIHwgbmJoIHwNCiAgICAgIG5iaC5yZWNhbGMNCiAgICBlbmQgDQog IGVuZA0KDQogIHByaXZhdGUNCg0KICBkZWYgbm9fbW9yZV92YXBvcj8NCiAgICAhIEB2YWx1ZXMu YW55P3sgfGxpbmV8DQogICAgICBsaW5lLmFueT97IHx2fCB2ID09IFZBUE9SIH0NCiAgICB9DQog IGVuZA0KDQogIGRlZiByZXNldF92YWx1ZXMNCiAgICBAdmFsdWVzID0gQXJyYXkubmV3KEBsaW5l cyl7DQogICAgICBBcnJheS5uZXcoQGNvbHVtbnMpew0KICAgICAgICBWQUNVVU0NCiAgICAgIH0N CiAgICB9DQogIGVuZA0KICBkZWYgc2V0X3ZhcG9ycw0KICAgIHRvdGFsID0gQGxpbmVzICogQGNv bHVtbnMNCiAgICB2ID0gKCBAdmFwb3JzICogICh0b3RhbC0xKSApLnRvX2kNCiAgICB4ID0gWyow Li50b3RhbC0yXQ0KICAgIGF0ID0gW10NCiAgICB2LnRpbWVzIGRvDQogICAgICBhdCA8PCB4LmRl bGV0ZV9hdCggcmFuZCh4LnNpemUpICkNCiAgICBlbmQNCiAgICBhdC5lYWNoIGRvDQogICAgICB8 IGluZGV4IHwNCiAgICAgIGwsYyA9IG1hdHJpeF9pZHggaW5kZXgNCiAgICAgIEB2YWx1ZXNbbF1b Y10gPSBWQVBPUg0KICAgIGVuZA0KICAgIEB2YWx1ZXNbQGxpbmVzLTFdW0Bjb2x1bW5zLTFdID0g QHZhbHVlc1tAc3RhcnQuZmlyc3RdW0BzdGFydC5sYXN0XQ0KICAgIEB2YWx1ZXNbQHN0YXJ0LmZp cnN0XVtAc3RhcnQubGFzdF0gPSBJQ0UNCiAgZW5kICMgZGVmIHNldF92YXBvcnMNCg0KICBkZWYg bGluZWFyX2lkeCByLCBjDQogICAgciAqIEBjb2x1bW5zICsgYw0KICBlbmQNCiAgZGVmIG1hdHJp eF9pZHggbA0KICAgIHJldHVybiBsIC8gQGNvbHVtbnMsIGwgJSBAY29sdW1ucw0KICBlbmQNCg0K ICBkZWYgd3JpdGUNCiAgICBAZm9ybWF0dGVyLnRvX2ZpbGUgc2VsZiwgIm91dHB1dC8je0BuYW1l fS4lMDhkIiAlIEBnZW5lcmF0aW9uDQogIGVuZCAjIGRlZiB3cml0ZQ0KICANCmVuZCAjIGNsYXNz IFRvcnVzXw0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMNCiMNCiMgICAgTmVpZ2hib3Job29kIGlzIGltcGxlbWVudGluZyBh IDJ4MiB3aW5kb3cgdG8gYW55IG9iamVjdA0KIyAgICB0aGF0IHJlc3BvbmRzIHRvICNbXW4sbSBh bmQgI1tdPW4sbSx2YWx1ZQ0KIyAgICBJdCBpbXBsZW1lbnRzIHRoZSBvcGVyYXRpb24gb2Ygcm90 YXRpb24uDQojDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj IyMjIyMjIyMjIyMjIyMjIyMNCmNsYXNzIE5laWdoYm9yaG9vZCA8IFN0cnVjdC5uZXcoIDp0b3J1 cywgOnRvcCwgOmJvdHRvbSwgIDpsZWZ0LCA6cmlnaHQgKQ0KICBpbmNsdWRlIEVudW1lcmFibGUN Cg0KICAjIE5laWdoYm9yaG9vZCBnaXZlcyB1cyB0aGUgZm9sbG93aW5nIGluZGV4ZWQgdmlldyB0 byB0aGUgdW5kZXJseWluZw0KICAjIHRvcnVzDQogICMgICAgICstLS0rLS0tKyAgICAgKy0tLS0t LS0tLS0tKy0tLS0tLS0tLS0tKw0KICAjICAgICB8IDAgfCAxIHwgICAgIHwgQHRvcCxAbGZ0IHwg QHRvcCxAcmd0IHwNCiAgIyAgICAgKy0tLSstLS0rICAgICArLS0tLS0tLS0tLS0rLS0tLS0tLS0t LS0rDQogICMgICAgIHwgMyB8IDIgfCAgICAgfCBAYm90LEBsZnQgfCBAYm90LEByZ3QgfA0KICAj ICAgICArLS0tKy0tLSsgICAgICstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSsNCiAgIw0KICAjIFRo ZSBOYW1lIGFuZCB0aGUgSW5kZXhlciBpbXBsZW1lbnQgdGhhdCBtYXBwaW5nDQoNCiAgTmFtZXMg PSBbIA0KICAgICAgJXd7IHRvcCBsZWZ0IH0sDQogICAgICAld3sgdG9wIHJpZ2h0IH0sDQogICAg ICAld3sgYm90dG9tIHJpZ2h0IH0sDQogICAgICAld3sgYm90dG9tIGxlZnQgfQ0KICAgICAgXQ0K DQogIGRlZiBpbml0aWFsaXplICphcmdzDQogICAgc3VwZXIgKmFyZ3MNCiAgZW5kDQoNCiAgYWxp YXNfbWV0aG9kIDpfX2FjY2Vzc19fLCA6W10gIyBOZWVkZWQgYi9jL28gdGhlIGxpbWl0ZWQgYWNj ZXNzDQogICMgYWJpbGl0aWVzIG9mIFN0cnVjdA0KDQogIGRlZiBbXSBuDQogICAgX19hY2Nlc3Nf XygidG9ydXMiKVsgKnJlc29sdmVfaWR4KCBuICkgXQ0KICBlbmQNCiAgZGVmIFtdPSBuLCB2YWwN CiAgICBfX2FjY2Vzc19fKCJ0b3J1cyIpWyAqcmVzb2x2ZV9pZHgoIG4gKSBdID0gdmFsDQogIGVu ZA0KDQogIGRlZiBlYWNoDQogICAgNC50aW1lcyBkbw0KICAgICAgfCBpZHggfA0KICAgICAgeWll bGQgc2VsZltpZHhdDQogICAgZW5kDQogIGVuZA0KDQogIGRlZiByZWNhbGMNCiAgICANCiAgICBp ZiBhbnk/e3x2fCB2ID09IElDRX0gdGhlbg0KICAgICAgNC50aW1lcyBkbw0KICAgICAgICB8IGlk eCB8DQogICAgICAgIHNlbGZbIGlkeCBdID0gSUNFIGlmIHNlbGZbIGlkeCBdID09IFZBUE9SDQog ICAgICBlbmQNCiAgICBlbHNlDQogICAgICByb3RhdGUoIHJhbmQoMikgKQ0KICAgIGVuZA0KICBl bmQNCg0KICBkZWYgcm90YXRlIGRpcg0KICAgIHggPSBzZWxmWzBdDQogICAgMy50aW1lcyBkbw0K ICAgICAgfCBuIHwNCiAgICAgIHNlbGZbIG4gKyAyKmRpcipuIF0gPSBzZWxmWyBuICsgMSArIGRp cioyKm4uc3VjYyBdDQogICAgZW5kICMgMy50aW1lcyBkbw0KICAgIHNlbGZbIDMgKyAyICogZGly IF0gPSB4DQogIGVuZCAjIGRlZiByb3RhdGUgZGlyDQoNCiAgcHJpdmF0ZQ0KICBkZWYgcmVzb2x2 ZV9pZHggbg0KICAgIFsNCiAgICBfX2FjY2Vzc19fKCBOYW1lc1sgbiAlIDQgXS5maXJzdCApLA0K ICAgIF9fYWNjZXNzX18oIE5hbWVzWyBuICUgNCBdLmxhc3QpDQogICAgXQ0KICBlbmQgIyBkZWYg cmVzb2x2X2lkeA0KDQplbmQgIyBjbGFzcyBOZWlnaGJvcmhvb2QNCg0K ------=_Part_20344_4369595.1173621305310--