車輪の再開発

勉強メモ

言語処理100本ノック 2020 (Rev 1)を解いてみる(05~09)

github.com

完走できるかは怪しい。
WIndows+python 3.8でちょろちょろ解いていく。

05. n-gram

与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ.この関数を用い,”I am an NLPer”という文から単語bi-gram,文字bi-gramを得よ.

以下のone-linerで書ける。 forでのoff-by-oneエラーに気を付けるべし。

def get_ngram(l: list, n: int):
    return [l[i:i+n] for i in range(len(l)-n+1)]

s = "I am an NLPer"
print(get_ngram(s.split(" "), 2))
print(get_ngram(s, 2))

06. 集合

paraparaparadise”と”paragraph”に含まれる文字bi-gramの集合を,それぞれ, XとYとして求め,XとYの和集合,積集合,差集合を求めよ.さらに,’se’というbi-gramがXおよびYに含まれるかどうかを調べよ.

setを使う。
各種集合に対する操作はsetが標準として持っている。

sx = "paraparaparadise"
sy = "paragraph"
x = set(get_ngram(sx, 2))
y = set(get_ngram(sy, 2))

print("union:", x.union(y))
print("intersection:", x.intersection(y))
print("diff:", x.difference(y))

search = "se"
if search in x:
    print(search + " is in x")
else:
    print(earch + " isn't in x")
if search in y:
    print(search + " is in y")
else:
    print(search + " isn't in y")

07. テンプレートによる文生成

引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ.さらに,x=12, y=”気温”, z=22.4として,実行結果を確認せよ.

pythonの文字列テンプレートは(公式の解説)https://docs.python.org/ja/3/library/string.html#string.Templateで十分わかりやすい。

from string import Template

def generate_template_message(x, y, z):
    s = Template("${X}時の${Y}は${Z}")
    return s.substitute(X=str(x), Y=str(y), Z=str(z))

print(generate_template_message(12, "気温", 22.4))

08. 暗号文

与えられた文字列の各文字を,以下の仕様で変換する関数cipherを実装せよ.
- 英小文字ならば(219 - 文字コード)の文字に置換
- その他の文字はそのまま出力
この関数を用い,英語のメッセージを暗号化・復号化せよ.

言われた通りのことを実装すれば問題ない。
文字からASCIIコードへの変換はord, ASCIIコードから文字への変換はchrでできる。
cipherを2回実行すると元の文字列に戻ることを確認した。
''' def cipher(s: str): return "".join([chr(219-ord(ch)) if ch.islower() else ch for ch in s])

s = "1aA2bB3cC4dD" print(cipher(s)) print(cipher(cipher(s))) '''

09. Typoglycemia

スペースで区切られた単語列に対して,各単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ.ただし,長さが4以下の単語は並び替えないこととする.適当な英語の文(例えば”I couldn’t believe that I could actually understand what I was reading : the phenomenal power of the human mind .”)を与え,その実行結果を確認せよ.

random.sampleを使う。
random.sampleはstrを受け付けないので、一度リストに変換した。
これなんですが、英語だからか長い英単語はスッと入ってきませんね。
英語が母国語の人は大丈夫なのかな…

''' import random

def mid_shuffle(s: str): if len(s) < 4: return s l = list(s) l[1:-1] = random.sample(l[1:-1], len(l)-2) return "".join(l)

s = "I couldn’t believe that I could actually understand what I was reading : the phenomenal power of the human mind ." print(" ".join([mid_shuffle(word) for word in s.split(" ")])) '''