こんにちは!じゃいごテックのあつしです。
今回はpaiza Bランクレベルアップメニュー からアルファベット探しという問題を解説します。
この問題集は文字列に関する3個のSTEP問題(D級)とFINAL問題(C級)で構成されていて、STEP問題を解いて行けばFINAL問題も解けるはず!となっています。
STEP問題を解いてみる
STEP問題は基本的なメソッドについての問題です。
簡単な解説は付けていますが、難しいと感じたら下記の記事も参考にしてみて下さい。
※過去に出題された小問題が出てくることがありますが、チケットに余裕があれば復習のつもりで取り組んでみましょう。
STEP1: 文字列の出力 (paizaランク D 相当)
STEP1 は3行の文字列をそのまま出力する問題です。
解答例
<<"EOS" 入力例1 kirishima kuroda rokumura 出力例1 kirishima kuroda rokumura 入力例2 tenshoku shinsotsu entry 出力例2 tenshoku shinsotsu entry 入力例3 Tokyo Osaka Nagoya 出力例3 Tokyo Osaka Nagoya EOS # [解答例1] a = gets.chomp b = gets.chomp c = gets.chomp puts a puts b puts c # [解答例2] N = 3 ary = N.times.map { gets.chomp } puts ary
解答例1 : 3行分の変数a, b, c
で入力を受け取り、そのまま出力しています。
解答例2 : 3行分の入力を配列ary
に格納してから、先頭から順に出力しています。
STEP2: アルファベットの範囲の文字の出力 (paizaランク D 相当)
STEP2 は与えられた大文字のアルファベット文字列の先頭文字から末尾文字までを順に出力する問題です。
※ 先頭文字は末尾文字よりもアルファベット順が早いことが保証されています。
解答例
<<"EOS" 入力例1 GINO 出力例1 G H I J K L M N O 入力例2 CZ 出力例2 C D E F G H I J K L M N O P Q R S T U V W X Y Z 入力例3 JP 出力例3 J K L M N O P EOS # [解答例1] # "A" から "Z" までの文字列 ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" s = gets.chomp top_idx = ALPHABET.index(s[0]) end_idx = ALPHABET.index(s[-1]) (top_idx..end_idx).each do |idx| puts ALPHABET[idx] end # [解答例2] s = gets.chomp top_chr = s[0] end_chr = s[-1] puts (top_chr..end_chr).to_a
解答例1: アルファベットA~Zまでの文字列ALPHABET
を用意し、与えられた文字列の先頭と末尾がALPHABETの何番目の文字かを調べ、先頭文字のインデックスから末尾文字のインデックスまでを順に出力しています。
解答例2: アルファベットで範囲オブジェクトを作成し、配列に変換して出力しています。
STEP3: アルファベットの順番 (paizaランク D 相当)
STEP3 は与えられた大文字のアルファベット文字列の先頭文字が末尾文字よりアルファベット順で先かを判定する問題です。
解答例
<<"EOS" 入力例1 GINO 出力例1 true 入力例2 CZ 出力例2 true 入力例3 VIOLIN 出力例3 false EOS # [解答例1] # "A" から "Z" までの文字列 ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" s = gets.chomp top_idx = ALPHABET.index(s[0]) end_idx = ALPHABET.index(s[-1]) if top_idx < end_idx puts "true" else puts "false" end # [解答例2] s = gets.chomp top_chr = s[0] end_chr = s[-1] puts top_chr < end_chr ? "true" : "false"
解答例1: アルファベットA~Zまでの文字列ALPHABET
を用意し、与えられた文字列の先頭と末尾がALPHABETの何番目の文字かを調べ、先頭文字のインデックスと末尾文字のインデックスの値で順番を判定しています。
解答例2: 先頭文字と末尾文字を文字のまま比較して、大小(前後)を判定しています。
(文字列は辞書順で比較され、大文字が先になっています -> "A" < "B" < "C" ... < "Z" < "a" < "b" < "c" ... < "z")
アルファベット探し (paizaランク C 相当)を解いてみる
※ paiza Bランクレベルアップメニューより
問題
1行目の英大文字 X から、2行目の英大文字 Y の範囲に3行目のアルファベット C が含まれていれば"true", そうでなければ"false"と出力してください。
X が Y よりもアルファベット順で後ろになる場合(X = 'G', Y = 'F'のときなど)も"false"と出力してください。
入力される値
入力は以下のフォーマットで与えられます。
X
Y
C
入力値最終行の末尾に改行が1つ入ります。
期待する出力
出力は、 "true" または "false" のどちらかです。
条件
すべてのテストケースにおいて、以下の条件をみたします。
- X, Y, Cはそれぞれ英大文字です。
- 入力例1
- A
D
C
- 出力例1
- true
- 入力例2
- D
D
D
- 出力例2
- true
- 入力例3
- A
D
Z
- 出力例3
- false
攻略ポイント
ポイント
問題を解く流れ
入出力例をコピペしてヒアドキュメントで変数に代入し、データを確認します。正しく受け取れていれば確認用コードは削除します。
INPUT1 = <<~"EOS" A D C EOS OUTPUT1 = <<~"EOS" true EOS INPUT2 = <<~"EOS" D D D EOS OUTPUT2 = <<~"EOS" true EOS INPUT3 = <<~"EOS" A D Z EOS OUTPUT3 = <<~"EOS" false EOS # 確認用コード p INPUT1 # > "A\nD\nC\n" p OUTPUT1 # > "true\n" p INPUT2 # > "D\nD\nD\n" p OUTPUT2 # > "true\n" p INPUT3 # > "A\nD\nZ\n" p OUTPUT3 # "false\n"
続いて問題を解くメソッド( solve
メソッドとします)を変数の下に定義します。
まず、入力データを受け取る処理を書きます。
def solve(input_lines) # 入力データ受け取り x, y, c = input_lines.split # 確認用コード [x, y, c] end # 確認用コード p solve(INPUT1) # > ["A", "D", "C"] p solve(INPUT2) # > ["D", "D", "D"] p solve(INPUT3) # > ["A", "D", "Z"]
データが正しく受け取れていれば、solve
メソッドに文字X
から文字Y
までの間に文字C
が含まれているかを調べる処理を追加していきます。
- 文字同士を比較する
def solve(input_lines) # 入力データ受け取り x, y, c = input_lines.split # x と y の間に c が含まれているか result = if x <= c && c <= y "true" else "false" end # 確認用コード result end # 確認用コード p solve(INPUT1) # > "true" p solve(INPUT1) == OUTPUT1 # > false p solve(INPUT2) # > "true" p solve(INPUT2) == OUTPUT2 # > false p solve(INPUT3) # > "false" p solve(INPUT3) == OUTPUT3 # > false
あとは出力形式を整えれば完成です。
p solve(INPUT1) == OUTPUT1 -> true
を確認するために、判定結果の末尾に改行を加えます。
def solve(input_lines) # 入力データ受け取り x, y, c = input_lines.split # x と y の間に c が含まれているか result = if x <= c && c <= y "true" else "false" end # 判定結果の末尾に改行を追加 result << "\n" end # 確認用コード p solve(INPUT1) # > "true\n" p solve(INPUT1) == OUTPUT1 # > true p solve(INPUT2) # > "true\n" p solve(INPUT2) == OUTPUT2 # > true p solve(INPUT3) # > "false\n" p solve(INPUT3) == OUTPUT3 # > true
入出力例での動作確認が出来ましたので、標準入力からのデータ受け取りに変更して、手動で動作確認をしたら提出します。
複数行のデータ受け取りなので STDIN.read
を使います。(入力終了は Ctrl+D
又は Ctrl+Z
)
解答コード
def solve(input_lines) # 入力データ受け取り x, y, c = input_lines.split # x と y の間に c が含まれているか result = if x <= c && c <= y "true" else "false" end # 判定結果の末尾に改行を追加 result << "\n" end puts solve(STDIN.read)
他の解答例
(文字X..文字Y)
で範囲オブジェクトを生成し、include?メソッド
でその中に文字C
が含まれているかを調べる。
def solve(input_lines) # 入力データ受け取り x, y, c = input_lines.split # x と y の間に c が含まれているか (x..y).include?(c).to_s end puts solve(STDIN.read)
今回のまとめ
- 文字(文字列)同士の比較を行いました
- 文字と使って範囲オブジェクトを生成しました
文字列同士の比較は並び替えとも関係しますので覚えておくと良いですね!