cf. どう書く?org – METHINKS IT IS A WEASEL
ずいぶん前に「ブラインドウォッチメイカー」を読んだ書いてみたもの。出遅れだし,お題ともちょっと違うので投稿せずにここにさらしておく。
IDEAL = "METHINKS IT IS LIKE A WEASEL" class Individual def initialize(phenotype) @phenotype = phenotype.upcase end attr_reader :phenotype def delivery next_phenotype = @phenotype.dup next_phenotype[rand(@phenotype.size)] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ".slice(ra nd(27), 1) Individual.new(next_phenotype) end def breed(n) next_generation = [] n.times do next_generation << delivery end next_generation end def to_s @phenotype end end class Nature def initialize(ideal) @ideal = ideal end def select(group) r = [] max = 0 group.each do |i| s = evaluate(i) if s > max max = s r = [i] elsif s == max r << i end end r[0] end def evaluate(ind) phenotype = ind.phenotype score = 0 0.upto(@ideal.size - 1) do |i| score += 1 if phenotype[i] == @ideal[i] end score end end if __FILE__ == $0 require 'optparse' def err_exit(msg) $stderr.print msg exit end options = {:number => 100} opts = OptionParser.new opts.banner = "Usage: ruby miilaw.rb [option] initial\n" opts.on_tail('-h', '--help', 'show this massage.') {puts opts; exit(0)} opts.on('-n', '--number=NUM', Integer, 'set number of children.') {|options[:numbe r]|} opts.parse! err_exit(opts.help) if ARGV.empty? len = IDEAL.size init = ARGV.shift.upcase if init.size < len init = "%-#{len}s" % init elsif init.size > len init = init[0,len] end individual = Individual.new(init) nature = Nature.new(IDEAL) genaration = 0 print "#{genaration} : #{individual}\n" while true do genaration += 1 next_gen = individual.breed(options[:number]) individual = nature.select(next_gen) print "#{genaration} : #{individual}\n" break if individual.phenotype == IDEAL end end