METHINKS IT IS A WEASEL
Posted feedbacks - Vim
やればできる子でした<Vim
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | :function! s:Random(n)
: if has('win32')
: let r = libcallnr("msvcrt", "rand", 0)
: else
: let r = libcallnr("libc", "rand", 0)
: endif
: return r % a:n
:endfunction
:function! s:MakeRandom()
: let res = ''
: for i in range(strlen(s:goal))
: let res = res . nr2char(char2nr('A')+s:Random(26))
: endfor
: return res
:endfunction
:function! s:CheckScore(line, goal)
: let score = 0
: for i in range(strlen(a:goal))
: let a = char2nr(strpart(s:goal,i,1))
: let b = char2nr(strpart(a:line,i,1))
: let d = a < b ? b - a : a - b
: let score = score + d
: endfor
: return score
:endfunction
:function! s:SortLines(num)
: for i in range(a:num)
: let line = getline(i+1)
: let score = s:CheckScore(line, s:goal)
: let line = printf("%05d:%s", score, line)
: call setline(i+1,line)
: endfor
": %!sort
: let lines = sort(getline(1,a:num))
: for i in range(a:num)
: call setline(i+1,strpart(lines[i],6,strlen(s:goal)))
: endfor
:endfunction
:function! s:ChangeLine(line_num, idx_num, var_num)
: for i in range(a:line_num)
: let line = getline(i+1)
: for j in range(a:var_num)
: let vline = line
: for k in range(a:idx_num)
: let split_idx = s:Random(strlen(s:goal))
: let head = strpart(vline,0,split_idx)
: let tail = strpart(vline,split_idx+1,strlen(s:goal))
: let vline = head .nr2char(char2nr('A')+s:Random(26)) . tail
: endfor
: call setline(a:line_num*(j+1)+i,vline)
: endfor
: endfor
:endfunction
:let s:initial_line_num = 300
:let s:change_idx_num = 1
:let s:variaty_num = 5
:let s:goal = "METHINKSITISAWEASEL"
:let s:start_time = localtime()
:new
:for s:i in range(s:initial_line_num)
: call setline(s:i+1, s:MakeRandom())
:endfor
:call s:SortLines(s:initial_line_num)
:let s:break_flag = 0
:while s:break_flag == 0
: call s:ChangeLine(s:initial_line_num,s:change_idx_num,s:variaty_num)
: call s:SortLines(s:initial_line_num * s:variaty_num)
: let s:line = getline(1)
: if s:line ==# s:goal
: let s:break_flag = 1
: endif
: echo getline(1)
:endwhile
:1
:let s:end_time = localtime()
:call append(0, (s:end_time - s:start_time) . " seconds elapsed")
|

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 ]