アナグラム・メーカー
ウェブアプリで考えるのではなく,コマンドライン上で動くものをまず作らない事には意味が無さそうなので,とりあえず考えはする.
事の発端
事の発端は某勉強会.いわゆる悪ふざけ.実用化されない.ちゃんと作り上げるかもわかんない.
最大の問題点
ただ文字の順番を入れ替えて表示するだけでは藝が無いし,辞書ファイルにある単語にマッチさせて,存在すれば表示,みたいな.
アナグラム - Wikipediaにも書いている事だけれど,
単純に考えてN文字ならNの階乗通り(例えば5文字なら120通り)の並べ替えが可能
だから,それをズラっと出すと大変な事になるのは目に見えている.
だから,ある程度の辞書が欲しい気がする.英単語ならEIJIROの辞書ファイルを使えば良さそうな気もするけれども,何処でも動くと言う前提が無くなるし,そもそも容量が大きすぎるので望ましくない.
もし日本語で使う事を仮定するなら,母音と子音を分け,それぞれの組み合わせで考えればまだ少なくなるかな?
プロトタイプ
何はともあれ,とりあえず動くものを作ろう.結果は全部出すんじゃなくて,ランダムでいいや.
class Array def shuffle! hoge = self.dup self.each_index do |i| e = rand(hoge.length) self[i] = hoge[e] hoge[e] = nil hoge.compact! end end def div_rand p = rand(self.length) before = self[0 .. p] after = self[p + 1 .. self.length - 1] return before, after end end def anagram(str = nil) return nil if str.nil? return str if str =~ /\d/ alpha = str.split(//) # 母音を抜き出す vocals = alpha.select{|e| e =~ /[aiueo]/} vocals.shuffle! # 混ぜる # 子音を抜き出す cons = alpha.select{|e| e !~ /[aiueo]/} cons.shuffle! # 混ぜる # 母音が子音より多ければ母音を一個抜き出しておく if vocals.length > cons.length vocal = vocals.shift else vocal = nil end # 子音,母音,子音と繋げていく result = [] cons.each do |e| result.push e, vocals.shift end before, after = result.div_rand # 適当な所で切る result = before << vocal << after # 強引 return result.to_s end
これでなんとかそれっぽい事はできる.
> anagram 'omochi' => "mihoco"
ミホコって誰.ボクのネカマハンドルにするか:p
課題
chなんかは一つに纏めてしまうってのもアリだなぁ.yやhは拗音に使えるし,この辺りも特別視すべきかな.この辺はイテレーションで.
できれば日本語で入力して日本語で吐き出したい.処理は勿論ローマ字に置き換えてやりたいな.ハッシュを使えば楽そうだ.