INDEX
■はじめに
Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。
基本的にはAtCoderというプログラミングコンテスト(競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)
(5/23時点の方針)
メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。
(2022/10/17時点の方針)
しばらくはB問題を小さい番号の方からやっていく。たまにA問題もやるかも。
■問題
●出典
AtCoder Beginner Contest 065のA問題
https://atcoder.jp/contests/abc065/tasks/abc065_a
●問題文
高橋君は胃が強いので、賞味期限を X 日まで過ぎた食品を食べてもお腹を壊しません。 賞味期限を X+1 日以上過ぎた食品を食べると、お腹を壊します。
また、賞味期限を過ぎずに食べると、おいしく感じます。そうでない場合、おいしく感じません。
高橋君は、賞味期限の A 日前に食品を買ってきて、買ってから B 日後に食べました。
高橋君が食品をおいしく感じた場合 delicious
を、おいしくは感じなかったがお腹は壊さなかった場合 safe
を、お腹を壊した場合 dangerous
を出力するプログラムを作成してください。
●制約
- 1≦X,A,B≦10^9
●入力
入力は以下の形式で標準入力から与えられる。
X A B
●出力
高橋君が食品をおいしく感じた場合 delicious
を、おいしくは感じなかったがお腹は壊さなかった場合 safe
を、お腹を壊した場合 dangerous
を出力せよ。
■回答
●愚直に書く
若干ややこしいが、紙に書き出して整理した。
- bがa+xより大きい→自動的に
dangerous
- bがa+x以下→bとaの比較で
safe
かdelicious
か決まる
となるので、下記のようにした。
x, a, b = gets.split.map(&:to_i)
if b > a + x
puts "dangerous"
elsif (b <= a + x) && (b > a)
puts "safe"
else
puts "delicious"
end
通った!
●メソッド化して書く
メソッドを作る練習のために、あえてそういう書き方をする。
def main
x, a, b = read_nums
puts is_expired?(x, a, b)
end
def is_expired?(x, a, b)
if b > a + x
"dangerous"
elsif (b <= a + x) && (b > a)
"safe"
else
"delicious"
end
end
def read_nums
gets.split.map(&:to_i)
end
main
通った!
●リファクタリング/別アプローチ
時間がないので割愛。
●他の方の回答例
皆さんの条件がシンプルだなと思って見ていたら、そうか、僕がelsif
でつけていた(b <= a + x)
は、if
の条件が当てはまらない時点で絶対にtrueだから書く必要がないのか。
つまり下記で良い。
x, a, b = gets.split.map(&:to_i)
if b > a + x
puts "dangerous"
elsif b > a
puts "safe"
else
puts "delicious"
end
あとは、今までちょっと避けていたけど入れ子の三項演算子を書いてみる。
x, a, b = gets.split.map(&:to_i)
puts b > a + x ? "dangerous" : b > a ? "safe" : "delicious"
可読性としてはifを使ったままの方が良い気もするけど、入れ子の三項演算子も慣れておきたい。
●出てきたメソッド等
公式リファレンスを見る訓練。
今回は特に無し。
■振り返りなど
久しぶりにA問題。条件にちょっと手間取ったけど比較的スムーズにできて良かった。