METHINKS IT IS A WEASEL
Posted feedbacks - Haskell
変異数:5。変異の仕方が文字列のどこか一文字をほかの文字と置き換える操作なので、スコアは正しい文字が正しい位置に何文字あるかで計算しています。
乱数生成がIOな関係上、やたらとIOな関数がいっぱい出てくるコードになっちゃいました。
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | module Main where
import System.Random
import Data.Array.IArray
import Data.List
import Data.Function
import Data.Ord
goal = "METHINKSITISAWEASEL"
score str = length $ filter (id) $ zipWith (==) str goal
updateRandom :: (Array Int Char) -> IO (Array Int Char)
updateRandom rg = do
ch <- randChar
i <- randPos
return $ rg // [(i, ch)]
genRandStr :: IO (Array Int Char)
genRandStr = do
str <- sequence $ replicate (length goal) (randChar)
return $ listArray (0, length goal - 1) str
randChar= getStdRandom $ randomR ('A', 'Z')
randPos = getStdRandom $ randomR (0, (length goal) - 1)
sortIt :: [Array Int Char] -> [Array Int Char]
sortIt = sortBy (\x y -> inverse $ (comparing (score.elems) x y))
where
inverse GT = LT
inverse EQ = EQ
inverse LT = GT
mutate :: [Array Int Char] -> IO [Array Int Char]
mutate strs = do
strs' <- mapM (updateRandomN 5) strs
return $ concat strs'
where
updateRandomN :: Int -> Array Int Char -> IO [Array Int Char]
updateRandomN n str = mapM (updateRandom) $ replicate n str
genMutation :: Int -> [Array Int Char] -> IO [Array Int Char]
genMutation i strs = do
strs' <- mutate strs
return $ take 300 $ sortIt strs'
doCycle :: Int -> [Array Int Char] -> IO ()
doCycle i strs = do
putStrLn $ (show i) ++ "th iteration:" ++ (elems $ head strs) ++ " : "
++ (show $ score $ elems $ head strs)
if (elems $ head strs) == goal then print "goal reached"
else genMutation i strs >>= doCycle (i + 1)
main :: IO()
main = do
strs <- sequence $ replicate 300 genRandStr
doCycle 0 $ sortIt strs
|

ytakenaka
#6287()
Rating4/8=0.50
ランダムな文字から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章で書いていた有名なものです。さらに一般化してもらってもいいです。
参考
[ reply ]