paiza プログラミング

[Ruby]paiza Bランクレベルアップメニュー アルファベット探し (paizaランク C 相当)の解説

B-lvup_アルファベット探し

こんにちは!じゃいごテックのあつしです。

今回は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)

今回のまとめ

  • 文字(文字列)同士の比較を行いました
  • 文字と使って範囲オブジェクトを生成しました

文字列同士の比較は並び替えとも関係しますので覚えておくと良いですね!



【PR】アルゴリズム学習でお世話になった本


アルゴリズム関連の技術書は大抵C/C++で書かれていますが、ある程度プログラムが出来れば、処理の流れは理解することが出来ます。






通称: 螺旋本。C++で解説されています。AOJ(Aizu Online Judge)を運営している会津大学の渡辺准教授が書いた本です。データ構造や計算量の内容から丁寧に書いてありますのでアルゴリズム学習の最初の参考書としてオススメです。







通称: 蟻本。C++で解説されています。競技プログラミング中級者の定番書と言われていて、競技プログラミングで利用できる色々なアルゴリズムを学ぶことが出来ます。かなり高度な内容も含まれているので1冊分を完全に理解するのにはかなりの時間がかかりそうですが、手元に置いて何度も読み返しています。







通称: チーター本。C#, C++, JAVAでTopcoderの問題を解説しています。初心者~中級者向けに書かれているので解説が非常に丁寧です。







Python3でアルゴリズムを解説している本です。講義スタイルの本で、図やフローチャートを使ってアルゴリズムとデータ構造についてしっかりと説明されています。代わりにコードは少なめです。Pythonコードが読めなくても十分理解できると思います。


-paiza, プログラミング
-, , ,

© 2024 じゃいごテック