paizaの森練習問題コンテストは、「paizaの森 (Discord)」にて約2か月に1回のペースで開催されており、ユーザー同士が開催時刻にpaizaの森に集まり「よーいドン」で与えられた数問の練習問題をお好きなプログラミング言語で解答する早さを競います。
( 第4回練習問題コンテストは D級10問 )
それほど難しい問題は出題されないですし、誤答によるペナルティーもありませんので初心者でも気軽に参加出来ます。
また、コンテストから数日後には出題された問題が一般公開され、だれでも挑戦できるようになります。
本記事で使用しているメソッド・アルゴリズムについて
解答例で使っているメソッドやアルゴリズムについて、下記の記事で詳しく解説していますので参考にしてみて下さい。
- [Ruby] 標準入力によるデータ取得1
- [Ruby] 標準入力によるデータ取得2
- [Ruby] 標準入力によるデータ取得3
- [Ruby] 標準出力(データを任意に整形して出力する)
- [Ruby] 文字列の連結・繰り返し・インデックス指定・置き換え
- [Ruby] 文字列を操作するメソッド
- [Ruby]ハッシュ(連想配列)の基本操作
- [Ruby]配列の基本操作1
- [Ruby]繰り返し処理
- [Ruby]条件分岐
- [アルゴリズム(Ruby)]線形探索法
- [アルゴリズム(Ruby)]動的計画法
第4回 paizaの森練習問題コンテスト
1問目: 花言葉 (paizaランク D 相当)
花の名前の文字列s
が与えられ、s
に対応する花言葉を出力する問題です。
なお、花の名前と花言葉の対応は下記の通り事前に与えられます。
- rose: I love you ※ バラ: あなたを愛しています
- cosmos: harmony ※ コスモス: 調和
- tulip: perfect lover ※ チューリップ: 理想の恋人
- hydrangea: heartlessness ※ アジサイ: 冷酷
- jasmine: amiability ※ ジャスミン: 愛嬌
入出力例
rose
が入力されたら、I love you
を出力する。jasmine
が入力されたら、amiability
を出力する。
INPUT1 = <<"EOS" rose EOS OUTPUT1 = <<"EOS" I love you EOS INPUT2 = <<"EOS" jasmine EOS OUTPUT2 = <<"EOS" amiability EOS
Ruby 解答例1-1
ハッシュで花言葉の対応を登録しておき、入力された文字列key
をキーにして値(花言葉)を出力します。
# 解答例1-1 hash = { "rose" => "I love you", "cosmos" => "harmony", "tulip" => "perfect lover", "hydrangea" => "heartlessness", "jasmine" => "amiability", } key = gets.chomp puts hash[key]
Ruby 解答例1-2
ハッシュのキーをシンボルにした書き方。打鍵数が少し減ります。
# 解答例1-2 hash = { rose: "I love you", cosmos: "harmony", tulip: "perfect lover", hydrangea: "heartlessness", jasmine: "amiability", } key = gets.chomp.to_sym puts hash[key]
Python3 解答例
辞書型で花言葉の対応を登録しておき、入力文字列key
をキーにして値(花言葉)を出力します。
# 解答例1 dict = { "rose": "I love you", "cosmos": "harmony", "tulip": "perfect lover", "hydrangea": "heartlessness", "jasmine": "amiability" } key = input() print(dict[key])
2問目: じゃんけん (paizaランク D 相当)
文字列s
でじゃんけんの手(R: グー, P: パー, S: チョキ)が与えられ、勝つ手を出力する問題です。
入出力例
R
が入力されたら、P
を出力する。
INPUT1 = <<"EOS" R EOS OUTPUT1 = <<"EOS" P EOS
Ruby 解答例1-1
if文で条件分岐します。
# 解答例1-1 h = gets.chomp res = if h == "R" "P" elsif h == "P" "S" elsif h == "S" "R" end puts res
Ruby 解答例1-2
case文で条件分岐します。
# 解答例1-2 h = gets.chomp res = case h when "R" "P" when "P" "S" when "S" "R" end puts res
Ruby 解答例2
じゃんけんの手を配列[グー: 0, パー: 1, チョキ: 2] として、相手の手s
に対応するインデックス+1を出す。
(チョキ:2 にグ ー: 0 で勝つためにインデックスを循環させる)
# 解答例2 RPS = %w(R P S) # RPS = ["R", "P", "S"] と同じ puts RPS[(RPS.index(gets.chomp) + 1) % RPS.length]
Python3 解答例1
# 解答例1 h = input() if h == "R": res = "P" elif h == "P": res = "S" elif h == "S": res = "R" print(res)
Python3 解答例2
# 解答例2 RPS = ["R", "P", "S"] print(RPS[(RPS.index(input()) + 1) % len(RPS)])
3問目: 四季 (paizaランク D 相当)
月の整数m
が与えられ、m
に対応する季節(spring, summer, autumn, winter)を出力する問題です。
なお、月と季節の対応は下記の通り事前に与えられます。
- spring : 3 ~ 5 月の期間
- summer : 6 ~ 8 月の期間
- autumn : 9 ~ 11 月の期間
- winter : 12 ~ 2 月の期間
入出力例
1
が与えられたらwinter
を出力する。
INPUT1 = <<"EOS" 1 EOS OUTPUT1 = <<"EOS" winter EOS
Ruby 解答例1-1
if文で条件分岐します。
# 解答例1-1 m = gets.to_i res = if m < 3 || m == 12 "winter" elsif m < 6 "spring" elsif m < 9 "summer" elsif m < 12 "autumn" end puts res
Ruby 解答例1-2
include?メソッドで条件分岐します。
# 解答例1-2 m = gets.to_i res = if [3, 4, 5].include?(m) "spring" elsif [6, 7, 8].include?(m) "summer" elsif [9, 10, 11].include?(m) "autumn" elsif [12, 1, 2].include?(m) "winter" end puts res
Ruby 解答例1-3
case文で条件分岐します。
# 解答例1-3 m = gets.to_i res = case m when 3, 4, 5 "spring" when 6, 7, 8 "summer" when 9, 10, 11 "autumn" when 12, 1, 2 "winter" end puts res
Python3 解答例1-1
if文で条件分岐します。
# 解答例1-1 m = int(input()) if m < 3 or m == 12: res = "winter" elif m < 6: res = "spring" elif m < 9: res = "summer" elif m < 12: res = "autumn" print(res)
Python3 解答例1-2
in演算子で条件分岐します。
# 解答例1-2 m = int(input()) if m in [3, 4, 5]: res = "spring" elif m in [6, 7, 8]: res = "summer" elif m in [9, 10, 11]: res = "autumn" elif m in [12, 1, 2]: res = "winter" print(res)
4問目: オルタネーティングキャップス (paizaランク D 相当)
アルファベット大文字・小文字混合の文字列s
が与えられ、全て小文字にした文字列を出力する問題です。
※ 第3回コンテストでも同じ問題が出題されていますので今回はさくっと解説します。
入出力例
pAIza
が入力されたらpaiza
を出力する。
INPUT1 = <<"EOS" pAIza EOS OUTPUT1 = <<"EOS" paiza EOS
Ruby 解答例
downcaseメソッドを使います。
# 解答例 puts gets.downcase
Python3 解答例
lowerメソッドを使います。
# 解答例 print(input().lower())
5問目: パワー 100 倍 (paizaランク D 相当)
整数pが与えられ、pを100倍した値を出力する問題です。
入出力例
813
が入力されたら81300
を出力する。123456789012345678901234567890
が入力されたら12345678901234567890123456789000
を出力する。
INPUT1 = <<"EOS" 813 EOS OUTPUT1 = <<"EOS" 81300 EOS INPUT2 = <<"EOS" 123456789012345678901234567890 EOS OUTPUT2 = <<"EOS" 12345678901234567890123456789000 EOS
Ruby 解答例1
整数で受け取って100倍します。
# 解答例1 puts gets.to_i * 100
Ruby 解答例2
文字列で受け取って、末尾に"00"を追加します。
# 解答例2 puts gets.chomp << "00"
Python3 解答例1
整数で受け取って100倍します。
# 解答例1 print(int(input()) * 100)
Python3 解答例2
文字列で受け取って、末尾に"00"を追加します。
# 解答例2 print(input() + "00")
6問目: おつり (paizaランク D 相当)
おつりの金額整数n
が与えられ、最小の硬貨枚数を出力する問題です。
なお、硬貨は 1円、5円、10円、50円、100円、500円の6種類で、各硬貨は何枚でも使えます。
入出力例
813
が入力されたら8
を出力する。
(500円: 1枚, 100円: 3枚, 50円: 0枚,10円: 1枚, 5円: 0枚, 1円: 3枚 ・・・ 合計 8 枚)
INPUT1 = <<"EOS" 813 EOS OUTPUT1 = <<"EOS" 8 EOS
Ruby 解答例1-1
額の大きい硬貨から順に、何枚使えるかを計算します。
# 解答例1-1 n = gets.to_i res = 0 # 500 円硬貨は使えるか pay500 = n / 500 res += pay500 n -= 500 * pay500 # 100 円硬貨は使えるか pay100 = n / 100 res += pay100 n -= 100 * pay100 # 50 円硬貨は使えるか pay50 = n / 50 res += pay50 n -= 50 * pay50 # 10 円硬貨は使えるか pay10 = n / 10 res += pay10 n -= 10 * pay10 # 5 円硬貨は使えるか pay5 = n / 5 res += pay5 n -= 5 * pay5 # 残りは1円硬貨で支払う (pay1 = n) res += n puts res
Ruby 解答例1-2
解答例1-1の処理を繰り返しでまとめた書き方。
# 解答例1-2 n = gets.to_i res = 0 [500, 100, 50, 10, 5, 1].each do |coin| res += n / coin n %= coin end puts res
Python3 解答例1-1
# 解答例1-1 n = int(input()) res = 0 # 500 円硬貨は使えるか pay500 = n // 500 res += pay500 n -= 500 * pay500 # 100 円硬貨は使えるか pay100 = n // 100 res += pay100 n -= 100 * pay100 # 50 円硬貨は使えるか pay50 = n // 50 res += pay50 n -= 50 * pay50 # 10 円硬貨は使えるか pay10 = n // 10 res += pay10 n -= 10 * pay10 # 5 円硬貨は使えるか pay5 = n // 5 res += pay5 n -= 5 * pay5 # 残りは1円硬貨で支払う (pay1 = n) res += n print(res)
Python3 解答例1-2
# 解答例1-2 n = int(input()) res = 0 for coin in [500, 100, 50, 10, 5, 1]: res += n // coin n %= coin print(res)
7問目: ゾロ目 (paizaランク D 相当)
11以上99以下の整数xが与えられ、x以下で最大のゾロ目を出力する問題です。
入出力例
60
が入力されたら55
を出力する。
INPUT1 = <<"EOS" 60 EOS OUTPUT1 = <<"EOS" 55 EOS
Ruby 解答例1-1
if文で条件分岐します。
# 解答例1-1 x = gets.to_i zoro = if x >= 99 99 elsif x >= 88 88 elsif x >= 77 77 elsif x >= 66 66 elsif x >= 55 55 elsif x >= 44 44 elsif x >= 33 33 elsif x >= 22 22 elsif x >= 11 11 end puts zoro
Ruby 解答例1-2
解答例1-1を繰り返しでまとめた書き方。
# 解答例1-2 x = gets.to_i zoro = -1 9.downto(1) do |i| tmp_zoro = i * 11 if x >= tmp_zoro zoro = tmp_zoro break end end puts zoro
Ruby 解答例2
10の位と1の位を比べて、
- 1の位が10の位以上なら 10の位のゾロ目を出力
- 1の位が10の位未満なら (10の位-1)のゾロ目を出力
# 解答例2 x = gets.chomp if x[0] <= x[1] puts x[0].to_i * 11 else puts (x[0].to_i - 1) * 11 end
Python3 解答例1-1
# 解答例1-1 x = int(input()) if x >= 99: zoro = 99 elif x >= 88: zoro = 88 elif x >= 77: zoro = 77 elif x >= 66: zoro = 66 elif x >= 55: zoro = 55 elif x >= 44: zoro = 44 elif x >= 33: zoro = 33 elif x >= 22: zoro = 22 elif x >= 11: zoro = 11 print(zoro)
Python3 解答例1-2
# 解答例1-2 x = int(input()) zoro = -1 for i in range(9, 0, -1): tmp_zoro = i * 11 if x >= tmp_zoro: zoro = tmp_zoro break print(zoro)
Python3 解答例2
# 解答例2 x = input() if x[0] <= x[1]: print(int(x[0]) * 11) else: print((int(x[0]) - 1) * 11)
8問目: いちばんお得 (paizaランク D 相当)
1行目に2番目のチョコの重さg1と価格p1、2行目に2番目のチョコの重さg2と価格p2がスペース区切りで与えられ、どちらのチョコが重さ当たりの価格が安いかをチョコの番号で出力する問題です。
入出力例
100 198
850 1728
が入力されたら
1
を出力する。
1番目のチョコのグラム当たりの価格: 198 ÷ 100 = 1.98 ← 安い
2番目のチョコのグラム当たりの価格: 1728 ÷ 850 = 2.03
INPUT1 = <<"EOS" 100 198 850 1728 EOS OUTPUT1 = <<"EOS" 1 EOS
Ruby 解答例1
チョコ1・チョコ2 それぞれのグラム当たり単価を計算して比較する。
# 解答例1 g1, p1 = gets.split.map(&:to_f) g2, p2 = gets.split.map(&:to_f) x1 = p1 / g1 x2 = p2 / g2 puts x1 < x2 ? 1 : 2
Ruby 解答例2
入力されたチョコのグラム当たり単価を計算した配列を生成して、昇順にソートして先頭のチョコ番号を出力する。
(この問題では蛇足ですが、チョコの種類がもっと多くなっても対応出来るので紹介します)
# 解答例2 price_per_grams = [] $stdin.read.split("\n").each.with_index(1) do |c, i| gram, price = c.split.map(&:to_f) price_per_grams << { number: i, price_per_gram: price / gram } end puts price_per_grams.sort_by { |c| c[:price_per_gram] }.first[:number]
Python3 解答例1
# 解答例1 g1, p1 = map(int, input().split()) g2, p2 = map(int, input().split()) x1 = p1 / g1 x2 = p2 / g2 print(1) if x1 < x2 else print(2)
Python3 解答例2
# 解答例2 price_per_grams = [] for i, c in enumerate(open(0).read().strip().split("\n"), 1): gram, price = map(int, c.split()) price_per_grams.append({"number": i, "price_per_gram": price / gram}) print(sorted(price_per_grams, key=lambda x: x["price_per_gram"])[0]["number"])
9問目: 重さの計算 (paizaランク D 相当)
求めたいボールの個数n、ボールの数k、k個のボールの重さx が与えられ、n個のボールの重さを小数切り捨ての整数で出力する問題です。
入出力例
13 5 504
が入力されたら1310
を出力する。
ボール1個当たりの重さ: 504 ÷ 5 = 100.8
13個のボールの重さ: 100.8 × 13 = 1310.4
1310.4の小数を切り捨てて 1310 を出力
INPUT1 = <<"EOS" 13 5 504 EOS OUTPUT1 = <<"EOS" 1310 EOS
Ruby 解答例1-1
1個当たりの重さを求めてから、求めたいボールの数を掛けます。
# 解答例1-1 n, k, x = gets.split.map(&:to_f) # 1 個の重さ(小数) weight = x / k # n 個の重さ(整数) puts (weight * n).to_i
Ruby 解答例1-2
解答例1-1をまとめた書き方。
# 解答例1-2 n, k, x = gets.split.map(&:to_f) puts (x / k * n).to_i
Python3 解答例1-1
# 解答例1-1 n, k, x = map(int, input().split()) # 1 個の重さ(小数) weight = x / k # n 個の重さ(整数) print(int(weight * n))
Python3 解答例1-2
# 解答例1-2 n, k, x = map(int, input().split()) print(int(x / k * n))
10問目: 寒暖差 (paizaランク D 相当)
10日間の最高気温が改行区切りの整数で与えられ、連続する2日の最高気温差が3度以上なら "Yes"、3度未満なら "No" を出力する問題です。
入出力例
27
28
29
29
28
30
25
26
28
30
が入力されたらYes
を出力する。
INPUT1 = <<"EOS" 27 28 29 29 28 30 25 26 28 30 EOS OUTPUT1 = <<"EOS" Yes EOS
Ruby 解答例1
i = 0 から 8 (10-2) の繰り返しで、 i 日目 と i+1 日目の最高気温を比較して、気温差3度を判定しています。
# 解答例1 n = 10 a = n.times.map { gets.to_i } temp_diff = false 0.upto(n - 2) do |i| if (a[i] - a[i + 1]).abs >= 3 temp_diff = true break end end puts temp_diff ? "Yes" : "No"
Ruby 解答例2
each_consメソッドで、連続する2日間の最高気温を参照・比較して、気温差3度を判定しています。
# 解答例2 a = $stdin.read.split.map(&:to_i) temp_diff = false a.each_cons(2) do |x, y| if (x - y).abs >= 3 temp_diff = true break end end puts temp_diff ? "Yes" : "No"
Python3 解答例1-1
i = 0 から 8 (10-2) の繰り返しで、 i 日目 と i+1 日目の最高気温を比較して、気温差3度を判定しています。
# 解答例1-1 n = 10 a = [ int(input()) for _ in range(n)] temp_diff = False for i in range(n-1): if abs(a[i] - a[i+1]) >= 3: temp_diff = True break print("Yes" if temp_diff else "No")
Python3 解答例1-2
i = 0 から 8 (10-2) の繰り返し&スライスで 連続する2日間の最高気温を比較して、気温差3度を判定しています。
# 解答例1-2 n = 10 a = list(map(int, open(0).read().strip().split())) temp_diff = False for i in range(n-1): x, y = a[i:i+2] if abs(x - y) >= 3: temp_diff = True break print("Yes" if temp_diff else "No")
Python3 解答例2
Ruby の each_consメソッド みたいなことをやりたかったのですが、複雑になっただけでメリットなかったかも・・・
# 解答例2 a = list(map(int, open(0).read().strip().split())) n = len(a) temp_diff = False for x, y in [a[i:i+2] for i in range(n-1)]: if abs(x - y) >= 3: temp_diff = True break print("Yes" if temp_diff else "No")
今回のまとめ
第4回はDランク問題10問のスピード勝負問題集でした!
とりあえず一回解いた後に、汎用性を持たせた書き方や簡単な書き方などを検討してみるのも勉強になりますね(*'ω'*)