METHINKS IT IS LIKE A WEASEL

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