AI要約
『SPY×FAMILY謎解き』に登場する「たぬき暗号」をPythonで解きました。形態素解析を活用して単語を調べる方法を詳しく解説。プログラムを用いた解読の過程を紹介しながら、SPY×FAMILYの世界観を楽しめる内容になっています。
やること
おはようございます、Suzuですヾ(・ω・ )
最近、SPY×FAMILY(スパイファミリー)がマイブームです。SPY×FAMILYは凄腕のスパイである黄昏が偽物の家族を作って東国の政治家と接触するというお話です。アニメは1期、2期とも観ました。映画も観ました。ヨルさんのように美人で強い女になりたいですねぇ()
さて、今回は2020年9月に開催されたキャンペーンの『SPY×FAMILY謎解き』に出てくる謎解き問題を解いてみました。全部で4問出題されるのですが、いちばん簡単な「たぬき暗号」をPythonで解いてみました。
問題
こちらの問題です。

これみよがしにたぬきが写っています。これは「た」を抜くという古典的な暗号です。
準備
日本語の形態素解析をするツール「janome」と、ひらがな⇔カタカナ変換のための「jaconv」をインストールしておきます。
pip install janome
pip install jaconv
「たぬき」の実行
「た」を「(無)」に置き換えることで「た」を削除します。
import jaconv
import itertools
from janome.tokenizer import Tokenizer
#問題
text = 'たたたたたったたぴたたなたたたたたーたたたたたつ'
#「たぬき」を実行
result = text.replace('た', '')
print(result)
っぴなーつ
「っぴなーつ」になりました!アーニャの好きな食べ物を知っていれば「ぴーなっつ」だと分かるのですが、見当がつかない場合はどうにかして単語を探さないといけません。
そこで、「っぴなーつ」を並び替えてできる120個の文字列について、日本語トークナイザーの「janome」で品詞を調べて判定するのはどうでしょうか?意味のある名詞と判定されれば、それがきっと答えに違いありません。
予備実験
予備実験として「janome」を用いて品詞を調べる方法を試してみます。
まず、正解である「ぴーなっつ」を品詞分解すると、
ぴ 名詞,一般,*,*,*,*,ぴ,*,*
ー 名詞,一般,*,*,*,*,ー,*,*
なっ 動詞,自立,*,*,五段・ラ行,連用タ接続,なる,ナッ,ナッ
つ 助動詞,*,*,*,下二・タ行,基本形,つ,ツ,ツ
4単語と判定されました。えー、「ぴーなっつ」って存在しないのですか・・・。
カタカナで「ピーナッツ」はどうでしょうか?
ピーナッツ 名詞,一般,,,,,ピーナッツ,ピーナッツ,ピーナッツ
1単語で一般名詞と出ました。
不正解である「ナッピーツ」はどうでしょうか?
ナッピーツ 名詞,固有名詞,組織,*,*,*,ナッピーツ,*,*
1単語ではありますが固有名詞と出ました。
これらの情報を使ってやっていきましょう。
並び替えた単語が存在するか?
「っぴなーつ」を並び替えてできる120個の文字列を「janome」で判定します。判定結果が「1単語」かつ「一般名詞」であれば「有効な単語です」と出力します。
#トークナイザー用意
tokenizer = Tokenizer()
#並び替えた文字列をトークナイザーで判定
for p in itertools.permutations(result):
#並び替えた文字列
word = ''.join(p)
print(word)
#品詞分解
tokens = tokenizer.tokenize(word)
#品詞ごとの品詞細分類1を集める
data = []
for token in tokens:
pos1 = token.part_of_speech.split(',')[1]
data.append(pos1)
# print(data)
#1単語かつ一般名詞であれば出力
if len(data) == 1 and data[0] == '一般':
print('↑有効な単語です')
っぴなーつ
っぴなつー
っぴーなつ
っぴーつな
っぴつなー
(中略)
つーっなぴ
つーぴっな
つーぴなっ
つーなっぴ
つーなぴっ
残念ながら検出されませんでした。予備実験のとき、ひらがなの「ぴーなっつ」は4単語になってしまっていたので仕方ありません。
カタカナでは存在するか?
今度はカタカナでも同様に判定します。
#並び替えた文字列をトークナイザーで判定
for p in itertools.permutations(result):
#並び替えた文字列
word = ''.join(p)
#カタカナに変換
kata = jaconv.hira2kata(word)
print(kata)
#品詞分解
tokens = tokenizer.tokenize(kata)
#品詞ごとの品詞細分類1を集める
data = []
for token in tokens:
pos1 = token.part_of_speech.split(',')[1]
data.append(pos1)
# print(data)
#1単語かつ一般名詞であれば出力
if len(data) == 1 and data[0] == '一般':
print('↑有効な単語です')
(前略)
ピナツッー
ピナツーッ
ピーッナツ
ピーッツナ
ピーナッツ
↑有効な単語です
ピーナツッ
ピーツッナ
ピーツナッ
ピツッナー
ピツッーナ
(後略)
「ピーナッツ」が有効な文字列として検出されました!成功です!
余談
ちなみに「たぬき暗号」と同じようなものには「けむし暗号」「まぬけ暗号」などがあります。以下のサイトではそういったものがたくさんリストアップされていて面白いです。

さいごに
ここまで記事を読んでいただきありがとうございました。Qiitaとnoteもやっていますのでフォローお願いします!
Qiita
note
