コンテンツへスキップ

【Ruby基礎】AtCoder Beginner Contest 029 B – カキ

■はじめに

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をちゃんと使いたいからメモ。

●出てきたメソッド等

公式リファレンスを見る訓練。

■振り返りなど

面白かったし解けて嬉しかったんだけど、メソッド化の練習になっているのかというと疑問が出てきた汗。