リファクタリングしてみたので、良かったらマージして下さい。

コードを変更した理由は各コミットにコメントとして書いています。