challenge METHINKS IT IS A WEASEL

ランダムな文字からMETHINKS IT IS A WEASELを作るプログラムを作れ。

簡単に流れを書いてみます。

1:ランダムな20文字を持つ文字列をもった300個作ります。

2:その文字列が"METHINKSITISAWEASEL"に近いものからソートします。

3:それぞれの文字列のなか1文字を別の文字に変化させたものを3つ用意します。

4:それを2:のソートをして上位300個残す。(900個あるうちで上位300個残すということです。)

5:以後3:と4:を繰り返す。

ランダムな文字変化は大文字だけでいいです。簡単にするために空白文字を外してあります。

METHINKS IT IS WEASELができたら終了。3と4の間でソートしたもので一番上位のものを毎回表示させると変化が楽しめます。:-)

Rickard Dawkinsがブラインドウォッチメイカー(現題:盲目の時計職人)の3章で書いていた有名なものです。さらに一般化してもらってもいいです。

参考

Posted feedbacks - Smalltalk

Squeak Smalltalk で。

ソートの際の比較は、文字とその位置の一致の数を調べる #howManyMatch: を使っています。三つでは収束しないので五つに変えました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| ゴール 全英字 文字数 上位群 世代数 |
ゴール := 'METHINKSITISWEASEL'.
文字数 := ゴール size.
全英字 := Character alphabet asUppercase.
上位群 := OrderedCollection new.
300 timesRepeat: [
    | 元文字列 |
    元文字列 := ((1 to: 文字数) collect: [:idx | 全英字 atRandom]) as: String.
    上位群 add: {元文字列 howManyMatch: ゴール. 元文字列}].
世代数 := 0.

World findATranscript:  nil.
[上位群 first last = ゴール] whileFalse: [
    | 候補群 |
    候補群 := OrderedCollection new.
    上位群 do: [:each |
        5 timesRepeat: [
            | 変異文字列 |
            変異文字列 := each last copy.
            変異文字列 at: 文字数 atRandom put: 全英字 atRandom.
            候補群 add: {変異文字列 howManyMatch: ゴール. 変異文字列}]].
    候補群 := 候補群 asArray sort: [:a :b | a first > b first].
    上位群 := 候補群 first: 300.
    Transcript cr; show: (世代数 := 世代数 + 1) -> 上位群 first].
^世代数

Index

Feed

Other

Link

Pathtraq

loading...