Traffine I/O

日本語

2023-02-03

言語処理100本ノック第1章:準備運動

はじめに

言語処理100本ノックというNLPに関する問題集が東京工業大学によって作成、管理されています。

https://nlp100.github.io/ja/ch01.html

この記事では、「第1章: 準備運動」について回答例を紹介します。

00. 文字列の逆順

文字列”stressed”の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.

print('stressed'[::-1])
desserts

01. 「パタトクカシーー」

「パタトクカシーー」という文字列の 1,3,5,7 文字目を取り出して連結した文字列を得よ.

print('パタトクカシーー'[0:7:2])
パトカー

02. 「パトカー」+「タクシー」=「パタトクカシーー」

「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.

char_list = [char1 + char2 for char1, char2 in zip('パトカー', 'タクシー')]
print(''.join(char_list))
パタトクカシーー

03. 円周率

“Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.

sentence = 'Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.'
result = [len(word.strip(',.')) for word in sentence.split()]
print(result)
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]

04. 元素記号

“Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.”という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19 番目の単語は先頭の 1 文字,それ以外の単語は先頭の 2 文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.

from pprint import pprint

sentence = 'Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.'
result = ({word[0] if i in {1, 5, 6, 7, 8, 9, 15, 16, 19} else word[:2]: i for i, word in enumerate(sentence.split(), 1)})
pprint(sorted(result.items(), key=lambda x:x[1]))
[('H', 1),
 ('He', 2),
 ('Li', 3),
 ('Be', 4),
 ('B', 5),
 ('C', 6),
 ('N', 7),
 ('O', 8),
 ('F', 9),
 ('Ne', 10),
 ('Na', 11),
 ('Mi', 12),
 ('Al', 13),
 ('Si', 14),
 ('P', 15),
 ('S', 16),
 ('Cl', 17),
 ('Ar', 18),
 ('K', 19),
 ('Ca', 20)]

05. n-gram

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

def ngram(n, lst):
  # [str[i:] for i in range(2)] -> ['I am an NLPer', ' am an NLPer']
  # zip(*[str[i:] for i in range(2)]) -> zip('I am an NLPer', ' am an NLPer')
  return list(zip(*[lst[i:] for i in range(n)]))

str = 'I am an NLPer'
words_bi_gram = ngram(2, str.split())
chars_bi_gram = ngram(2, str)

print('word bi-gram:', words_bi_gram)
print('char bi-gram:', chars_bi_gram)
word bi-gram: [('am', 'an'), ('I', 'am'), ('an', 'NLPer')]
char bi-gram: [('I', ' '), (' ', 'N'), ('e', 'r'), ('a', 'm'), (' ', 'a'), ('n', ' '), ('L', 'P'), ('m', ' '), ('P', 'e'), ('N', 'L'), ('a', 'n')]

06. 集合

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

def ngram(n, lst):
  return list(zip(*[lst[i:] for i in range(n)]))

str1 = 'paraparaparadise'
str2 = 'paragraph'
X = set(ngram(2, str1))
Y = set(ngram(2, str2))
union = X | Y
intersection = X & Y
difference = X - Y

print('X:', X)
print('Y:', Y)
print('union:', union)
print('intersection:', intersection)
print('difference:', difference)
print('X included in se:', {('s', 'e')} <= X)
print('Y included in se:', {('s', 'e')} <= Y)
X: {('a', 'r'), ('a', 'p'), ('s', 'e'), ('p', 'a'), ('r', 'a'), ('i', 's'), ('d', 'i'), ('a', 'd')}
Y: {('p', 'h'), ('a', 'r'), ('a', 'p'), ('p', 'a'), ('g', 'r'), ('r', 'a'), ('a', 'g')}
union: {('p', 'h'), ('a', 'r'), ('a', 'p'), ('s', 'e'), ('p', 'a'), ('g', 'r'), ('r', 'a'), ('i', 's'), ('a', 'g'), ('d', 'i'), ('a', 'd')}
intersection: {('p', 'a'), ('r', 'a'), ('a', 'r'), ('a', 'p')}
difference: {('d', 'i'), ('i', 's'), ('a', 'd'), ('s', 'e')}
X included in se: True
Y included in se: False

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

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

def create_sentence(x,y,z):
    return f'{str(x)}時の{str(y)}{str(z)}'

print(create_sentence(12, '気温', 22.4))
12時の気温は22.4

08. 暗号文

与えられた文字列の各文字を,以下の仕様で変換する関数 cipher を実装せよ.

  • 英小文字ならば(219 - 文字コード)の文字に置換
  • その他の文字はそのまま出力

この関数を用い,英語のメッセージを暗号化・復号化せよ.

def cipher(str):
    rep = [chr(219 - ord(x)) if x.islower() else x for x in str]
    return ''.join(rep)

sentence = 'I am titanium.'
sentence = cipher(sentence)
print('encrypt:', sentence)
sentence = cipher(sentence)
print('decrypt:', sentence)
encrypt: I zn grgzmrfn.
decrypt: I am titanium.

09. Typoglycemia

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

import random

sentence = 'I couldn’t believe that I could actually understand what I was reading : the phenomenal power of the human mind .'
print(' '.join(i[0] + ''.join(random.sample(i[1:-1], len(i[1:-1]))) + i[-1] if len(i) > 4 else i for i in sentence.split()
))
I clnuo’dt beevile that I culod aactully unrsntdead what I was rdianeg : the pahenomenl peowr of the human mind .

参考

https://nlp100.github.io/ja/about.html
https://nlp100.github.io/ja/ch01.html

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!