コンテンツへスキップ

Ruby初心者がAtCoderの過去問から多くの学びを得るために工夫していること

  • by

こんにちは、sugieこと@hiromisugieです。

INDEX

■はじめに

この記事は、フィヨルドブートキャンプのアドベントカレンダー2022、11日目の記事です。
フィヨルドブートキャンプのアドベントカレンダー2022は、Part1とPart2があります。
☞ フィヨルドブートキャンプ Part 1 Advent Calendar 2022
☞ フィヨルドブートキャンプ Part 2 Advent Calendar 2022

Part1の10日目は、まいむさんによる「【名前重要】と向き合っている話」でした。

Part2の10日目は、nicole 2525さんによる「仕事をしながらパートナーと学習する日々について」でした。


●この記事は何か?

AtCoderの過去問を自分でコツコツ解くようになったsugieが、少しでも色々なことを学びとするために工夫していることを紹介していく記事です。

「AtCoderをやってみようかな?」と思っている方の参考になれば嬉しいですし、諸先輩方の「もっとこうしてみたら」というアドバイスがあれば嬉しいです🙏


●用語説明

この記事で頻繁に出てくる用語についてご説明します。

  • フィヨルドブートキャンプ
    • sugieが入会しているNiceなプログラミングスクール。以下、略称のFBCと表記します。
  • AtCoder
    • 「競技プログラミング」と呼ばれるコンピュータプログラムのコンテストを行うサービス。オンラインで毎週コンテストを開催していますが、sugieはRubyの練習のために過去問を解いています。
  • 勝手にモブプロ会
    • FBCの先輩で卒業生のはるぐちさんが定期的(現在は不定期)にFBC内のDiscordで開催している会。何人かでDiscordのボイスチャットをつないで、AtCoder過去問のA問題とB問題をワイワイ解いています。この会のおかげでsugieはAtCoderを知り、後述するように自分でも解くようになりました。

■AtCoder過去問を解く際の流れ

上述のように、「勝手にモブプロ会」でAtCoderを知ったsugieは競プロの面白さの一端を知り、また、もっとRubyに慣れ親しむために、AtCoderの過去問を解くようになりました。そして、自分の回答やそこで得られた気づき等をブログに上げています。

ここからは、自分がAtCoder過去問をどのように進めているのか、また、どんなことに気を付けているのかを、実際に最近解いた問題と共にご紹介していきます。(意図が伝わりやすくするために、実際のブログ記事から少しだけ加筆修正しています)

ここで例に出している問題→AtCoder Beginner Contest 070のA問題


①問題を読む

まず最初に問題を読みます。問題文とともに制約条件、入力例も載っているので、それらを見ながら問題の意味するところを理解していきます。

この時の問題文は以下の内容でした。

●問題文
3 桁の正の整数 N が与えられます。
N が 回文数であるかを判定してください。
回文数とは、10 進法において数字を逆から並べても元の数と同じになる数のことを表します。
 
●制約
100 ≦ N ≦ 999
N は整数
 
●入力
入力は以下の形式で標準入力から与えられる。

N

●出力
N が回文数である場合は Yes、そうでない場合は No を出力せよ。
 
A - Palindromic Number より引用)


②愚直に書く

まずはコードの綺麗さなどのことは置いておいて、答えを出すことを優先して書いていきます。できるだけ思考の流れも書いたり、途中うまくいかなかったことも書き留めておくようにしています。

この時は、下記のような流れで考えていきました。

ひっくり返しても等しければ Yesという感じかな?

n = gets.chomp
if n == n.reverse
  puts 'Yes'
else
  puts 'No'
end

そしてif式を三項演算子にして、

n = gets.chomp
puts n == n.reverse ? 'Yes' : 'No'

通った!


③メソッド化する

これは途中から始めた施策です。当時FBCの課題を進めている際に、メソッド化に苦手意識を持っていたので、シンプルな内容でもメソッドを定義してみる、という練習をしています。

この時は、下記のようにメソッドを定義しました。

メインメソッド、回文かどうかを判定するメソッド、標準入力を受け取るメソッドの3つを作成。

def main
  n = read_str
  puts is_palindromic?(n)
end

def is_palindromic?(n)
  n == n.reverse ? 'Yes' : 'No'
end

def read_str
  gets.chomp
end

main

④リファクタリングする

はじめに作った愚直な解答を元にもっとシンプルに書けないか探ったり、あるいは別のアプローチや別メソッドで解けないかを探ります。

この時は、下記のように書いていきました。

3桁であることが保証されているから、1文字目と3文字目が等しければ回文になるか。

n = gets.chomp
puts n[0] == n[2] ? 'Yes' : 'No'

通った!


⑤他の方の回答を見る

ここまで来たら他の方の回答を見ていきます。

僕はコード長の短い順にソートして確認していますが、最上位の方々は魔法のような記述をしていて理解が追いつかなかったりするので、最上位から順番に見ていきつつ自分の回答を良くするヒントになるような解答や、自分の思いつかなかったアプローチをしている解答をメインに探していきます。

この時は、下記をメモしていました。

考え方はほぼ一緒だったけど、いくつかメモ。
 
・ n[0] == n[2]でジャッジするのでchompは不要。なるほど。
・ n / 100 == n % 10でもジャッジできる。面白い。


⑥るりまで、メソッドを確認する

自分のコードや他の方のコードに登場したメソッドについて、Ruby リファレンスマニュアル(通称るりま)で確認します。

この時は、下記のようなメソッドを確認しました。

String#reverse
https://docs.ruby-lang.org/ja/latest/method/String/i/reverse.html
 
String#[]
https://docs.ruby-lang.org/ja/latest/method/String/i/=5b=5d.html


⑦振り返り

気づいたことや思ったことを書きます。ガッツリ書こうとすると時間がかかるので、思いついたことをメモする程度です。
(この時は、他の方の回答の部分で書いていたこともあり、振り返り部分の記載は無しでした)


⑧おまけ:学習内容をGitHubで管理

これも途中から始めたのですが、ターミナルの操作やGitHubの操作に慣れるということも兼ねて、上記で書いたコードを自分のリポジトリにアップしています。GitHubの草も生えるし、一石二鳥!


■AtCoder過去問を解くことで得られるもの

上述のように解いていくことで、以下のような学びを得られているかなと思います。


①まず「愚直に書く」こと

頭の中でウンウン考えるのではなく、まず手を動かしていくことで、解答に近づくことができます。
「勝手にモブプロ会」でも「ひとまず愚直に書いてみますか!」というように進めていくことが多く、その精神を学べただけでも大きな収穫だったと思います。


②リファクタリングの練習

あまりに時間をかけすぎても良くないとは思いますが、「前にも似たような問題があったな」とか「これってもしかしてこっちのメソッドでできる?」といったことを考えて実行してみることは、コードをシンプルにしたり別アプローチをする練習になり、Ruby脳を鍛える練習になっていると思います。


③他の回答からの学び

これも時間が許す範囲での実施にはなりますが、上位解答者の皆さんのコードにはたくさんの学びが詰まっています。AtCoderは競プロという性質上、「いかに短く書くか」という力学が働いています。その結果、最上位の方の解答はまるで魔法のように短いものもあり、自分の実力では解読すらできないことも多いですが、それでも色々な解答を見られることは勉強になることが多く、ありがたいです。


④ターミナルやGit操作への慣れ

自分はまだまだターミナル操作やGitHubでのコード管理に慣れていないので、「AtCoderで解いたコードをGitHubにあげる」というだけて単純に「毎日ターミナルを触っている」ことになり、それだけでも今の自分にとっては大きな経験となっています。


このように、Ruby初心者な自分にとってはひとつの問題からたくさんの学びを得ることができています。


■おわりに

「一粒で二度・三度もおいしい」AtCoderでの練習ですが、最近はA問題だけでなくB問題にもチャレンジしており、先日A問題70問、B問題30問で合計100問を突破しました!

ただし、B問題は今の自分では手こずることも多く、まだまだ修行していきたい所存です。
また、現在はFBCの課題に注力するためにかなりペースダウンしていますが、これからもAtCoderは続けていきたいと思っており、「勝手にモブプロ会」も引き続き参加していきたいです!


ここまで読んでいただき、ありがとうございました!

思えば、昨年のアドベントカレンダーで「【フィヨルドブートキャンプ】働きながらプログラミングの学習をして2ヶ月が経ちました」と書いて、はや一年。あわよくば今年卒業できるかななんて淡い期待をしていましたが、全然ダメでした涙。
来年のアドカレでは自作サービスについて書けるように、引き続き頑張っていきます!


明日のフィヨルドブートキャンプ アドベントカレンダーは以下の予定です。

Part1の12日目:Hikaruさん
Part2の12日目:cafedomancerさん


■おまけの猫

気がつくと全く画像の無い記事でしたので、うちの猫を貼っておきます。

今年の7月から飼い始めている保護猫2匹です。本日のアドベントカレンダーPart2を書かれているhirano-vm4(けだま)さんの記事で知りましたが、偶然にも今日のアドカレを書いた2人は2匹の保護猫を飼っていました🐈🐈‍⬛