言語処理100本ノック 2015 第1章 00〜04


言語処理100本ノック 2015」というのを知ったので、ちょっとpythonの勉強のつもりでチャレンジ開始。
まずは「第1章: 準備運動」の00から順に着手。

00. 文字列の逆順

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

こんな関数で実現してみました。スライス使うだけですね。

def func00(source):
    """
    >>> func00('stressed')
    'desserts'
    """
    return source[::-1]

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

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

同じくスライスを使うだけですね。

def func01(source):
    """
    >>> func01('パタトクカシーー')
    'パトカー'
    """
    return source[::2]

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

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

zip関数使って[(‘パ’, ‘タ’),(‘ト’, ‘ク’),…]というタプルのシーケンスを作っておいて、x+yで[‘パタ’, ‘トク’,…]というシーケンスにした上で、joinを使って1つの文字列に…という作りです。

def func02(source1, source2):
    """
    >>> func02('パトカー', 'タクシー')
    'パタトクカシーー'
    """
    return ''.join([x + y for x, y in zip(source1, source2)])

03. 円周率

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

いけているかどうかはわかりませんが、これもワンライナーで書いてみました。

def func03(source):
    """
    >>> func03('One, two, three.')
    [3, 3, 5]
    """
    return [len() for x in source.split()]

まずsplitを使って文字列のリストに分割。それぞれの文字列に対してlenで文字列長を取得すれば簡単なのですが、例題には「,」「.」が含まれており、わざわざ「(アルファベットの)」という注記が入っていることから、アルファベットだけのリストに作り直してからlenで要素数を数えるようにしてみました。
ちなみに課題に書かれている”Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文字列を入力すると

[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文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.

1行がちょっと長くなってきたので、2行に分割。

def func04(source, pos):
    """
    >>> func04('One Two Three.', [1, 3])
    {'O': 1, 'Tw': 2, 'T': 3}
    """
    t = source.split()
    return {x[:1 if i + 1 in pos else 2]: i + 1 for i, x in list(enumerate(t))}

enumerateを使ってインデックスを付けることで「何番目」という要求に対応。
1,5,6,…はposで受け取るのですが、インデックスがposで指定された中に含まれていれば1文字、そうでなければ2文字、というのをスライスを使って実現してみました。
ちなみに、課題の”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]を引数で渡して実行することで、以下のような辞書を取得できます。

{'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}

まず00〜04までの5題をやってみましたが、どこまで続けられるかな?

スポンサーリンク

フォローする

スポンサーリンク