paiza プログラミング

[Ruby|Python]paiza paizaの森練習問題コンテスト過去問題4

paiza_forest_contest_004

paizaの森練習問題コンテストは、「paizaの森 (Discord)」にて約2か月に1回のペースで開催されており、ユーザー同士が開催時刻にpaizaの森に集まり「よーいドン」で与えられた数問の練習問題をお好きなプログラミング言語で解答する早さを競います。
( 第4回練習問題コンテストは D級10問 )
それほど難しい問題は出題されないですし、誤答によるペナルティーもありませんので初心者でも気軽に参加出来ます。
また、コンテストから数日後には出題された問題が一般公開され、だれでも挑戦できるようになります。

本記事で使用しているメソッド・アルゴリズムについて

解答例で使っているメソッドやアルゴリズムについて、下記の記事で詳しく解説していますので参考にしてみて下さい。

第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ボールの数kk個のボールの重さ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を出力する。

temp_diff

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問のスピード勝負問題集でした!

とりあえず一回解いた後に、汎用性を持たせた書き方や簡単な書き方などを検討してみるのも勉強になりますね(*'ω'*)



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


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






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







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







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







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


-paiza, プログラミング

© 2024 じゃいごテック