はじめに
Ruby学習の一環として「競技プログラミング(競プロ)」に挑戦します。
そのための学習の中で学んだことをアウトプットしていきます。
今回は「AtCoder Beginners Contest168」の一問目(Therefore)より。
https://atcoder.jp/contests/abc168/tasks/abc168_a
自分が使った解法と、公式から公開された解説をもとにまとめていきます。
問題
日本語で鉛筆を数える時には数の後ろに助数詞として「本」がつきます。
この助数詞はどんな数につくかで読み方が異なります。
999以下の整数について、「N本」と言う時の「本」の読み方は、
・Nの1の位が「2,4,5,7,9」の時は'hon'
・Nの1の位が「0,1,6,8」の時は'pon'
・Nの1の位が「3」の時は'bon'
Nが与えられるので、対応する「本」の読み方を出力しなさい。
制約
Nは999以下の正の整数
入力は以下の形で与えられる。
N
# 例
16
上記の例だと最大2回割ることができるので
出力例
# 上記例の場合
=> pon
解答①
まずは僕が最初に書いたコードです。
a = gets.to_i.modulo(10)
if [2,4,5,7,9].include?(a)
print "hon"
elsif [0,1,6,8].include?(a)
print "pon"
else
print "bon"
end
moduloメソッドを使って、入力から一の位のみを受け取り、
if文とinclude?メソッドで判定を行っていきます。
include?メソッドについては、以下の記事について一度書いたので、
AtCoder Beginners SelectionでRuby学習【Some Sums】使えるメソッドを増やす
ここでは、moduloメソッドについて触れておきます。
moduloメソッド
指定した数で割った余りを返します。
解答では、整数を10で割ることで一の位を余りとして取り出しています。
# 例
13.modulo(4)
=> 1
42.modulo(10)
=> 2
解答② case文
コンテスト後に配布された解説では、
case文による、より直感的に記述できる方法が紹介されています。
以下ではcase文で解答した後に、case文の紹介をしていきます。
n = gets.to_i.modulo(10)
case n
when 2,4,5,7,9
print 'hon'
when 0,1,6,8
print 'pon'
else
print 'bon'
end
最初の解答では、条件を配列に入れてinclude?メソッドで判定をしていましたが、
case文を使うことで、「一の位がもし2,4,5,7,9だったら…」と考えたままのコードが書けています。
確かにこっちの方が良さそうです。
case文
一つの値に対して複数の候補の中から一致するものを探す時に便利です。
whenで指定するものに一致するかどうかを「===」演算子によって判定します。
case object
when value1
# object === value1の時に実行する文
when value2
# object === value2の時に実行する文
else
# 全てに合致しなかった場合に実行する文
end
ここで出てきた「===」演算子は、
上記で言うobjectが文字列や数値の場合は、「==」として、
正規表現の場合は「=~」として、
範囲の場合はinclude?のようにその中にvalueを含むかと、言う形で判定してくれるようです。
柔軟で、使い勝手が良さそうです。
最後に
以上、「AtCoder Beginners Contest168」の一問目(Therefore)から学んだメソッドをご紹介しました。
もし間違いなどございましたら、ご指摘いただけると嬉しいです。