■はじめに
Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。 基本的にはAtCoderというプログラミングコンテスト(競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)
(5/23時点の方針) メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。
(2022/10/17時点の方針) しばらくはB問題を小さい番号の方からやっていく。たまにA問題もやるかも。
■問題
●出典
AtCoder Beginner Contest 078のA問題 https://atcoder.jp/contests/abc078/tasks/abc078_a
●問題文
プログラミングでは 16 進数がよく使われます。 16 進数では 0,1,...,9 の数字の他に A, B, C, D, E, F の 6 つのアルファベットを使い,それぞれ 10,11,12,13,14,15 を表します。 この問題では 2 つのアルファベット X,Y が与えられます。 X と Y はどちらも A, B, C, D, E, F のうちどれかです。 X と Y を 16 進数として見たとき,どちらのほうが大きいかを判定してください。
●制約
- X,Y は A, B, C, D, E, F のうちどれかである。
●入力
入力は以下の形式で標準入力から与えられる。
X
Y
●出力
X のほうが小さいならば <
, Y のほうが小さいならば >
, 等しいならば =
と出力してください。
■回答
●愚直に書く
問題がややこしいけど、要はABCDEFの中から2文字がチョイスされてそれを比較すれば良さそう。
a, b = gets.split
if a > b
puts ">"
elsif a < b
puts "<"
else
puts "="
end
通った!
●メソッド化して書く
メソッドを作る練習のために、あえてそういう書き方をする。 久しぶりなのでやってみるか…!
メインメソッド、大小記号を判定するメソッド、標準入力を取得するメソッドの3つを作成。 久しぶりすぎて忘れていたので過去投稿も参考にしつつ作成した。
def main
a, b = read_str
puts judge(a, b)
end
def judge(a, b)
if a > b
">"
elsif a < b
"<"
else
"="
end
end
def read_str
gets.split
end
main
通った!
●リファクタリング/別アプローチ
if文のところもうちょっとスッキリできそうな気がするけど思いつかないなぁ。
なんとなく宇宙船演算子(<=>
)が活かせそうな気がするんだけどうまく落とし込めない。
と思いながら過去の自分の投稿で宇宙船演算子が出てきたものを見返していたら思いついた!
a, b = gets.split
puts "=><"[a <=> b]
通った〜〜〜うれしい!!
ちなみに参照した過去記事はこちら https://sugie.co/2022/11/22/ruby-abc071a/
今回でいうと、a <=> b
を評価した時に-1
か0
か1
が返って来るので、=><
という文字列のインデックス部分に[a <=> b]
を入れることで下記のようになる。
- aがbより手前の文字→宇宙船演算子で
-1
が返る→puts "=><"[-1]
なので<
が出力 - aがbと同じ文字→宇宙船演算子で
0
が返る→puts "=><"[0]
なので=
が出力 - aがbより後の文字→宇宙船演算子で
1
が返る→puts "=><"[1]
なので>
が出力
●他の方の回答例
上位層はほとんど宇宙船演算子を使っていた。 三項演算子の入れ子を使っている人もチラホラ。
●出てきたメソッド等
公式リファレンスを見る訓練。
- Ruby の <=> 演算子が返す値を覚える方法 https://qiita.com/takuya0301/items/364f2b3f7ba2c36e0f62 公式リファレンスじゃないけどメモ