■はじめに
Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。 基本的にはAtCoderというプログラミングコンテスト(競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)
(5/23時点の方針) メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。
■問題
●出典
AtCoder Beginner Contest 029のB問題 https://atcoder.jp/contests/abc029/tasks/abc029_b
●問題文
英小文字からなる 12 個の文字列 S1 , S2 , ..., S12 が入力されます。 これらの文字列のうち、文字 r が含まれるものの個数を数えてください。
●入力
入力は以下の形式で標準入力から与えられる。
S1
S2
:
S12
- i 行目 (1 ≦ i ≦ 12) に、英小文字からなる文字列 Si (1 ≦ ∣Si∣ ≦ 10) が与えられる。 これらの文字列はすべて異なる。
●出力
標準出力に、 12 個の文字列 S1 , S2 , ..., S12 のうち文字 r が含まれるものの個数を出力し、最後に改行せよ。 r を複数個含む文字列は一度だけ数える。
■回答
●メソッド化して書く
今回はいきなりメソッド化して作っていく。 標準入力を取るのがまずどうやるんだっけというやつだ…汗。
複数行はreadlines
だったはずだけど、末尾の\n
を取るのがreadlines.chomp
だとうまくいかない。readlines
で取ってきた入力は配列になっているので、map
してループ内でchomp
すれば良いはず。
続いてmainメソッド。
まずread_words
を変数に入れる。
今回は、要素内にr
が含まれているかどうかを調べたい。select
メソッドとinclude?
メソッドの合わせ技でできそう。
select
で該当する要素を抽出したら、その要素を数えるのはcount
メソッド。
def main
words = read_words
puts words.select { |word| word.include? "r" }.count
end
def read_words
readlines.map do |word|
word.chomp
end
end
main
通った!思ったより早く解けて嬉しい…!
●リファクタリング/別アプローチ
ふと思ったが、何も考えずに書く要素末尾の\n
を削除することに苦戦したけど、最終的にputs
するし\n
が残っていてもいいのでは…。もしそうなら取得用のメソッドはシンプルになる。
def main
words = read_words
puts words.select { |word| word.include? "r" }.count
end
def read_words
readlines
end
main
通った! そうか、これでも良いのか。
●他の方の回答例
入力を取る方法はreadlines
じゃなくても12.times.map{gets}
でも良いっぽい。gets
をちゃんと使いたいからメモ。
●出てきたメソッド等
公式リファレンスを見る訓練。
-
Array#filter (
select
のエイリアス) https://docs.ruby-lang.org/ja/latest/method/Array/i/filter.html -
String#include? https://docs.ruby-lang.org/ja/latest/method/String/i/include=3f.html
■振り返りなど
面白かったし解けて嬉しかったんだけど、メソッド化の練習になっているのかというと疑問が出てきた汗。