#はじめに
現在paizaのBランク問題突破を目指して学習中です。今回は、アルファベット探しという問題に関して勉強になったので解法をまとめておきます。
記述方法によってコードが大幅に削減されるという事を実感しました。
こちらの問題です↓↓
https://paiza.jp/works/mondai/prob60/alphabets_large_or_small_9
#問題文
1行目の英大文字 X から、2行目の英大文字 Y の範囲に3行目のアルファベット C が含まれていれば"true", そうでなければ"false"と出力してください。
X が Y よりもアルファベット順で後ろになる場合(X = 'G', Y = 'F'のときなど)も"false"と出力してください。
入力例1
A
D
C
出力例1
true
問題を要約すると
「1行目と2行目の文字の間に、3行目の文字が含まれていれば"true"と出力させる」
という内容です。
#自分の解答
まずは自分の回答をまとめます
回答の方針としては
①まず3行の標準出力を変数に格納する(その際にordメソッドで文字コードに変換)
②1行目と2行目の間の全ての文字をeach文で出力する
③もしも3行目の文字が含まれていた場合countする。
④最後にcountに従って、"true" or "false"を出力する。
以下が実際のコードです。
num1 = gets.chomp.ord
num2 = gets.chomp.ord
num3 = gets.chomp.ord
is_count = false
(num1..num2).each do |i|
if i == num3
is_count = true
end
end
puts is_count
これで無事に出力できたので、正解でした。
しかしコードが長い。。
#模範回答
以下が模範回答でした。
string = []
3.times { string.push(gets.chomp) }
puts string[0].ord <= string[2].ord && string[2].ord <= string[1].ord
①配列を用意する
②times文の中で、配列に入力値をpushする
③配列[2]が配列[0]よりも大きいかつ、配列[1]よりも小さいときに "true”と出力する
10行から3行になった。
配列にpushするという発想がなかったです。
また比較の仕方も、if文を使う必要がないという部分は勉強になりました。
#追記 リファクタリングに挑戦
編集リクエストありがとうございます!アドバイスをもとにリファクタリングに挑戦します!
①文字列は比較できるので、ordメソッドは必要ない
ordメソッドを使わなくても文字列は比較できるということは意外でした。
例えば以下のように使えます。
"か".between?("あ","け") => true
コードを修正すると、
puts string[0].ord <= string[2].ord && string[2].ord <= string[1].ord
↓↓
puts string[0] <= string[2] && string[2] <= string[1]
②betweenメソッドを使う
範囲を比較する場合はbetween?を使うと見やすいですね。
puts puts string[0] <= string[2] && string[2] <= string[1]
↓↓
puts string[2].between?(string[0],string[1])
改めて全体のコードです。
string = []
3.times { string.push(gets.chomp) }
puts string[2].between?(string[0],string[1])
コードが見やすく、シンプルになりました!
#まとめ
今回は機能としては動くものの、記述方法によって大幅に短くなる。
という事を改めて実感したので記事にまとめてみました。
この調子で効率の良い記述方法など、学んでいきます。