この挑戦は、もう精神的にPythonesqueであるかのように... マルコフ連鎖や暗号化技術の予備知識は必要ありません。
あなたはイギリスの警備サービスM1Sから重要な情報を入手する必要があるスパイです。M1Sのエージェントは、Wi-Fi信号が傍受される可能性があること、Android / iOSのセキュリティ脆弱性が悪用されることなどを十分に認識しているため、全員がNokia 3310を使用して、T9自動補完を使用して入力されるテキスト情報を送信しています。
あなたは以前に電話をハッキングしてagency報機関に配送し、キーロガーを素晴らしいプラスチックキーボードの下にインストールしていたので、入力した文字に対応する一連の数字を受け取るので、「ワシは巣から離れてエージェントに警告します」
84303245304270533808430637802537808430243687
ちょっと待って!一部のT9シーケンスはあいまいです(「6263」は「name」、「mane」、または「oboe」になる可能性があります。不明瞭になるほど、疑わしくなります!)、どうしますか?M1Sが使用する入学試験は、マルセルプルーストの傑作「過去の記憶」を15秒で要約することだけなので、chef-d全体の頻度分布に従って、前の単語の次に来る単語を選択します。プルーストの傑作!
コードを解読して、元のメッセージを入手できますか?
T9の原理
T9自動補完メカニズムは、次のように説明できます。上の図に示すように、アルファベット文字を数字にマップします。
abc -> 2
def -> 3
ghi -> 4
jkl -> 5
mno -> 6
pqrs -> 7
tuv -> 8
wxyz -> 9
<space> -> 0
<other> -> <is deleted>
T9復号化装置は一連の数字を受け取り、それらのキーを押して入力できる単語を推測しようとします。標準の頻度表を使用することもありますが、さらに一歩進んで、マルコフ連鎖を使用して次の単語を予測しています!
学習サンプル
コーパスは、プルーストの「物事過去の思い出」のこの重く取り除かバージョン(s/-/ /g
、s/['’]s //g
およびs/[^a-zA-Z ]//g
-仰せられた混乱所有格's
!)もともとに掲載さアデレード大学のウェブサイト(この作品のテキストは、オーストラリアでのパブリックドメインです)。
テキスト全体が一つの長い単語のベクトルとして、一つの長い文として、1つの文字列として分析する必要があります(あなたの言語のためのより便利な方)、改行が取り除かれ、スペースで単語に分割。(単一のパラグラフファイルは、githubツールによって眉をひそめられる可能性があるため、提供していません。)
テキスト全体を1つの文字列/文として読み取るにはどうすればよいですか?Rの例:
p_raw <- read.table("proust.txt", sep="\t") # Because there are no tabs
p_vec <- as.character(p_raw$V1) # Conversion to character vector
p_str <- paste(p_vec, collapse=" ") # One long string with spaces
p_spl <- strsplit(p_str, split=" ")[[1]] # Vector of 1360883 words
proust <- p_spl[p_spl!=""] # Remove empty entries — 1360797
仕事
数字のシーケンスを数値として指定すると、確率チェーンを使用して対応するT9キーを使用して入力できるテキスト文字列を返し、1つの長い文として扱われるこのトレーニングテキストに基づいて次の単語Xを予測します。
場合Xは、テキストの最初のT9ワードであり、複数の推測があり、そうでない可能性だけを選んで、ランダムに1つ選択。
すでに解読された単語w(i-1)が先行する後続のすべてのT9単語X(i )について:
- T9ワードXを1つのユニークな方法で通常のワードxに変換できる場合、それを行います。
- Xに対して複数の変換オプション(たとえばx1、x2、...)が利用可能な場合、前に推測された単語wを検索します。
- Proustの元の作品でwの後にXにマッピングされるものが続かない場合は、可能なx1、x2、...のいずれかをランダムに選択します。
- 場合XはWいつもに対応ワット×1元にして何の同時存在しないXIにマップすることができさんXは、選ん×1 。
- 場合はXをWに変換することができワット×1 、ワット×2 、それはコーパスで見つけることができます...、そして、すべての可能なカウントXIをあのフォローをwをしてにマッピングXコーパスにして選ぶXIを確率でXI /(X1 + X2 + ...) 。
例2a。メッセージがある場合76630489
、ここで489
あり得るguy
か、ivy
(それらが少なくとも一度コーパスに起こる)、7663
のように解読することができるsome
(非常に有望な最初の単語)。場合some
にマップするものが続くことはありません489
コーパスでは、その後、選択guy
またはivy
確率0.5でランダムに。
例2b。メッセージがあるなら766302277437
、どこに2277437
あるbarrier
かcarrier
、または7663
として解読できますsome
。プルーストが常に使用しsome carrier
、使用しないsome barrier
場合は、選択しsome carrier
ます。
例2c。シーケンスを解読するとします536307663
。5363
として予測されたlend
。7663
次のいずれかになります:pond
、roof
およびsome
。lend
サンプルコーパス内の後続の単語の出現回数をカウントします。次のようなものが得られると仮定します(説明のためだけに):
T9 Word following lend Occurrences
7663 some 7
7663 pond 2
7663 roof 1
もしそう7663
で先行されlend
、そこにある7/(7+2+1)=70%
確率7663
を意味しsome
、20%pond
と10% roof
。アルゴリズムはlend some
、70%の場合、lend pond
20%の場合などで生成する必要があります。
エージェントはa〜zの文字とスペースのみを使用していると安全に想定できます(句読点、所有格's
、数字は使用していません)。
また、M1Sのエージェントは、「過去の記憶」の範囲外の言葉(29,237語の途方もないボキャブラリーです!)を使用しないと想定することもできます。
T9機能はこのチャレンジで実装されたので、ご覧ください。
助けが必要な場合、確率的連鎖はこれ、それ、および以下の課題で見事に飼いならされましたが、そのような連鎖の原理を知る必要さえありません:すべてがタスクで述べられています。
テストケース
--Inputs--
20784250276960369
20784250276960369
84303245304270533808430637802537808430243687
94280343084306289072908608430262780482737
94280343084306289072908608430262780482737
--Possible outputs--
c quick brown fox
a stick crown fox
the eagle gas left the nest blest vie agents
what did the navy pay to the coast guards
what did the navy raz un the coast guards
ルール:
- 標準の抜け穴が適用されます。
- 元のメッセージがわからないため、一連の数字とproust.txtファイルだけをメモリ/ワークスペース/何でもロードする必要があります。自己完結型のものを用意する必要はありません。
proust.txt
常にアクセス可能であると仮定します。 - コーパスに従って複数の復号化オプションが考えられる場合、アルゴリズムはそれぞれの確率で異なる出力を生成できる必要があります(例2cを参照)。
できるだけ目立たないようにする必要があるため、最短のコードが優先されます!
PSこの確率的アルゴリズムの明らかな利点は、あいまいな解読された文字列に対して真の元の文字列を取得する確率が1になる傾向があるという事実です。
PPS 部分一致による予測 も参照してください。