mocchaso note

サーバーエンジニアが何か色々呟いているところ。

Python100本ノック 82本目〜89本目(81本目〜88本目)

Python100本ノック、82本目から89本目についてです。

qiita.com


82本目:TwoSums


問題:整数配列とターゲットが渡された時、整数配列の内足したら答えがターゲットになる2つの数字を返しなさい。
例:twosums([2, 7, 11, 15], 9) ==> 2, 7

特に問題無く解けました。
以下のようなやり方でコーディングしてみました。

  • targetより大きい値を排除したリストを新しく定義する

  • そのリストについて二重ループさせ、条件が一致する組み合わせを探索する

Qiita記事ではcombinationというメソッドを使っていました。知らなかった...!


83本目:Reverse Integer


問題:渡される整数を逆にして返せ。

リストのスライスを使えなかったこと以外は、特に問題無く解けました。
応急処置として、for文を降順に回して別の変数に1文字ずつ格納しました。

リスト(ここでは文字列)を逆順にするのは、list[::-1]でした。
前にもリストのスライス使った気がするんですが、忘れてました。
その時より細かく調べた感じ、以下の仕様みたいですね。
参考サイト:‭ Pythonのスライス

sliced_list = list[start_idx:end_idx:step]

  • start_idx番目~end_idx - 1番目までの要素を部分的に取得できる。

  • 最後の要素のインデックスは、end_idx+1となる。

  • 3つ目のstepはスライスの幅。負の値を指定すると逆向きにスライスできる。
    (Reverse Integerではこの仕様を使っています)


84本目:Roman to Int


問題:(0~4999)までのローマ字を数字に変換せよ。ちなみにローマ数字と整数は以下。

let romanValues = [“M”, “CM”, “D”, “CD”, “C”, “XC”, “L”, “XL”, “X”, “IX”, “V”, “IV”, “I”]
let arabicValues = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]


特に問題無く解けた、と思いきやQiita記事の実装とわりと違ってて「!?」となりました。 その違いについて調べてみたところ、減算則の実装し忘れでした。というか知らなかった。

  • 減算則
    小さい数を大きい数の左側に書いたとき、右の数字から左の数字だけ引くルール。
    (例えば、IVなら-1+5=4)
    参考サイト:‭ローマ数字 - Wikipedia

FFとかドラクエでIVって書いて4と読むのはそういう仕組みだったんですね...。


85本目:Valid Paretheses


問題: (), {}, []など、括弧が有効であるかチェックをしてBoolを返しなさい。

解法が全然思い浮かばなかったのでググりました。
辿り着いたブログ記事の序盤の文章だけ見て取り組みました。
しかし、そこで紹介されているアルゴリズムは、括弧の種類が複数の場合には対応していませんでした。
参考サイト:‭ソフ開のアルゴリズムの勉強 - 元データ分析の会社で働いていた人の四方山話

そこで、Qiita記事の解法を読み、括弧の種類を判別する方法として辞書を採用しました。
この時、

return False if len(stack) else True

の部分がよく分かりませんでしたが、解決できました。
三項演算子で書かれているのは分かりましたが、if文の条件のlen(stack)が謎で...笑

stackが空ならFalse、1つでも要素が含まれていたらTrueと判定するんですね。
簡単なコードを書いて実際に試してみることで理解できました。


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


特に問題無く解けました。
自分は地道にインデックスを指定して結合させましたが、
Qiita記事では文字列(リスト)のスライスを用いていました。


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


特に問題無く解けました。
Qiita記事の解法がめっちゃスッキリしていました。
str.join()にリスト内包表記を応用することで短縮化していました。

※間違ってq86(q85)を飛ばしてこっちからやってしまった笑


88本目:単語の文字数


特に問題無く解けました。
q76(q75)でstr.replace()メソッドについて以前調べた時、
空白文字を指定することで",""."を排除できることが分かりました。
それを用いて単語の境界を空白文字だけにして、単語の文字数をカウントしてやりました。


89本目:Typoglycemia


問題:
スペースで区切られた単語列に対して、各単語の先頭と末尾の文字は残し、それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ。
条件:
長さが4以下の単語は並び替えない。
例:
"I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind ."

特に問題無く解けました。Qiita記事とほぼ同じ方針でした。

randomライブラリでシャッフルするメソッドが無いか調べたところ、出てきました。
参考サイト:‭Pythonでリストの要素をランダムソート(シャッフル) | note.nkmk.me

  • random.shuffle(list)
    引数に指定したリストの要素をランダムに並び替えられる。指定した元のリストが更新される。

  • random.sample(list, element_size)
    リストからランダムに要素を選択し取得するメソッド。
    第2引数は、取得したい要素の個数が入る。
    shuffle()とは異なり、元のリストは変更せず、ランダムに並び替えられた新たなリストを作る。




ここ数回の投稿で考える系の問題が増えてきましたが、今回で更に増えた感じがしました。
一番苦労したのは、Valid Parenthesesです。

かなり終わりが見えてきました。
終盤ということもあって、思考力が鍛えられる問題になっています。
ただ実装するだけ+どうやったら効率の良いコードになるかも考えることを
引き続き意識して取り組みたいと思います!