paiza プログラミング

[Ruby]paiza Bランクレベルアップメニュー 足すか掛けるか (paizaランク C 相当)の解説

B-lvup_足すか掛けるか

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

今回はpaiza Bランクレベルアップメニュー から足すか掛けるかという問題を解説します。

この問題集は繰り返しと条件分岐に関する4個のSTEP問題(D級)FINAL問題(C級)で構成されていて、STEP問題を解いて行けばFINAL問題も解けるはず!となっています。

STEP問題を解いてみる

STEP問題は繰り返しと条件分岐の基本問題です。
簡単な解説は付けていますが、難しいと感じたら下記の記事も参考にしてみて下さい。

※過去に出題された小問題が出てくることがありますが、チケットに余裕があれば復習のつもりで取り組んでみましょう。

STEP1: インクリメント (paizaランク D 相当)

STEP1 は受け取った整数をインクリメント(+1)して出力する問題です。

解答例

<< EOS

入力例1
-10
出力例1
-9
入力例2
0
出力例2
1
入力例3
1
出力例3
2

EOS

n = gets.to_i
puts n + 1

解答例: 標準入力で受けとった文字列を整数型に変換、+1 して出力しています。


STEP2: 文字列の出力 (paizaランク D 相当)

STEP2 はn個の改行区切りの文字列をそのまま出力する問題です。

解答例

<<"EOS"

入力例1
3
AB
CD
EF

出力例1
AB
CD
EF

入力例2
3
1
2
3

出力例2
1
2
3

入力例3
3
a
b
c

出力例3
a
b
c

EOS

# [解答例1]
n = gets.to_i
n.times { puts gets }

# [解答例2]
n = gets.to_i
ary = n.times.map { gets.chomp }
puts ary

解答例1: 1行目で受け取ったn回の繰り返しを設定し、続くn行分の文字列をそのまま出力しています。

解答例2: n行の文字列を一旦配列aryに格納してから、各要素を改行区切りで出力しています。


STEP3: 文字列の分割 (paizaランク D 相当)

STEP3 はスペース区切りの2つの文字列を改行区切りの2行で出力する問題です。

解答例

<<"EOS"

入力例1
Hello World

出力例1
Hello
World

入力例2
apple orange

出力例2
apple
orange

入力例3
12 345

出力例3
12
345

EOS

# [解答例1]
a, b = gets.split
puts a
puts b

# [解答例2]
ary = gets.split
puts ary

解答例1: 半角スペース区切りの文字列を別の変数に代入して、それぞれ出力しています。

解答例2: 半角スペース区切りの文字列を一旦配列aryに格納して、配列の要素を改行区切りで出力しています。


STEP4: 整数の足し算 (paizaランク D 相当)

STEP4 はスペース区切りの2つの整数を足した値を出力する問題です。

解答例

<<"EOS"

入力例1
0 0

出力例1
0

入力例2
1 2

出力例2
3

入力例3
10 20

出力例3
30

EOS

# [解答例1]
a, b = gets.split.map(&:to_i)
puts a + b

# [解答例2]
puts gets.split.map(&:to_i).sum

解答例1: 半角スペース区切りの文字列を整数型に変換して別の変数に代入して、足したものを出力しています。

解答例2: 角スペース区切りの文字列を整数型に変換して配列にして、sumメソッドで合計値を求めて出力しています。

足すか掛けるか (paizaランク C 相当)を解いてみる

※ paiza Bランクレベルアップメニューより

問題

2つの整数の組がn個与えられるので、各組の計算結果を足し合わせたものを出力してください。
各組の計算結果は次の値です。

  • 2つの整数の組を足し合わせたもの
  • ただし、2つの整数が同じ値だった場合は、掛け合わせたもの

入力される値

入力は以下のフォーマットで与えられます。

n
a_1 b_1
...
a_n b_n

nは与えられる整数の組の行数です。
a_iとb_iはそれぞれが整数です。

入力値最終行の末尾に改行が1つ入ります。

期待する出力

各行の計算結果を足し合わせた値を出力してください。
最後は改行し、余計な文字、空行を含んではいけません。

条件

すべてのテストケースにおいて、以下の条件をみたします。

  • 1 ≦ n ≦ 50
  • -100,000 ≦ a_n ≦ 100,000
  • -100,000 ≦ b_n ≦ 100,000
入力例1
5
2 1
3 6
4 2
4 4
4 70
出力例1
108
入力例2
1
0 0
出力例2
0
入力例3
3
1 2
3 4
5 6
出力例3
21
攻略ポイント

ポイント

  • 半角スペース区切りの整数を受け取る(二次元配列)
  • 繰り返しと条件分岐の組み合わせ

デバッグを楽にするためにメソッドを作成します。メソッドについては下記の記事も参考にしてみて下さい。

問題を解く流れ

入出力例をコピペしてヒアドキュメントで変数に代入し、データを確認します。正しく受け取れていれば確認用コードは削除します。

INPUT1 = <<~"EOS"
  5
  2 1
  3 6
  4 2
  4 4
  4 70
EOS
OUTPUT1 = <<~"EOS"
  108
EOS

INPUT2 = <<~"EOS"
  1
  0 0
EOS
OUTPUT2 = <<~"EOS"
  0
EOS

INPUT3 = <<~"EOS"
  3
  1 2
  3 4
  5 6
EOS
OUTPUT3 = <<~"EOS"
  21
EOS

# 確認用コード
p INPUT1
# > "5\n2 1\n3 6\n4 2\n4 4\n4 70\n"
p OUTPUT1
# > "108\n"
p INPUT2
# > 1\n0 0\n"
p OUTPUT2
# > "0\n"
p INPUT3
# > "3\n1 2\n3 4\n5 6\n"
p OUTPUT3
# > "21\n"

続いて問題を解くメソッド( solve メソッドとします)を変数の下に定義します。

まず、入力データを受け取る処理を書きます。

def solve(input_lines)
  # 入力データ受け取り
  input_lines = input_lines.split("\n")
  n = input_lines.shift.to_i
  ary = []
  input_lines.shift(n).each do |line|
    ary.push(line.split.map(&:to_i))
  end

  # 確認用コード
  [n, ary]
end

# 確認用コード
p solve(INPUT1)
# > [5, [[2, 1], [3, 6], [4, 2], [4, 4], [4, 70]]]
p solve(INPUT2)
# > [1, [[0, 0]]]
p solve(INPUT3)
# > [3, [[1, 2], [3, 4], [5, 6]]]

データが正しく受け取れていれば、solve メソッドに二次元配列aryについて計算する処理を追加していきます。

  • 配列aryの各要素の1番目と2番目の要素について調べる
    • 1番目と2番目の要素の値が同じなら掛け算をする
    • 1番目と2番目の要素の値が異なるなら足し算をする
  • 各要素で計算した結果を全て足して出力する
def solve(input_lines)
  # 入力データ受け取り
  input_lines = input_lines.split("\n")
  n = input_lines.shift.to_i
  ary = []
  input_lines.shift(n).each do |line|
    ary.push(line.split.map(&:to_i))
  end

  # 配列 ary の各要素を計算して合計を求める
  result = 0
  ary.each do |a, b|
    if a == b
      result += a * b
    else
      result += a + b
    end
  end

  # 確認用コード
  result
end

p solve(INPUT1)
# > 108
p solve(INPUT1) == OUTPUT1
# > false
p solve(INPUT2)
# > 0
p solve(INPUT2) == OUTPUT2
# > false
p solve(INPUT3)
# > 21
p solve(INPUT3) == OUTPUT3
# > false

あとは出力形式を整えれば完成です。

p solve(INPUT1)puts solve(STDIN.read) (p solve(STDIN.read)でも可)に変更すれば正解となりますが、p solve(INPUT1) == OUTPUT1 -> true を確認するために、結果を改行区切りの文字列に変換して、末尾にも改行を加えます。

def solve(input_lines)
  # 入力データ受け取り
  input_lines = input_lines.split("\n")
  n = input_lines.shift.to_i
  ary = []
  input_lines.shift(n).each do |line|
    ary.push(line.split.map(&:to_i))
  end

  # 配列 ary の各要素を計算して合計を求める
  result = 0
  ary.each do |a, b|
    if a == b
      result += a * b
    else
      result += a + b
    end
  end

  # 文字列型に変換して末尾に改行を追加する
  result.to_s << "\n"
end

p solve(INPUT1)
# > "108\n"
p solve(INPUT1) == OUTPUT1
# > true
p solve(INPUT2)
# > "0\n"
p solve(INPUT2) == OUTPUT2
# > true
p solve(INPUT3)
# > "21\n"
p solve(INPUT3) == OUTPUT3
# > true

確認用コードを標準入力からのデータ受け取りに変更して、動作確認をしたら提出します。
複数行のデータ受け取りなので STDIN.read を使います。(入力終了は Ctrl+D 又は Ctrl+Z)

解答コード
def solve(input_lines)
  # 入力データ受け取り
  input_lines = input_lines.split("\n")
  n = input_lines.shift.to_i
  ary = []
  input_lines.shift(n).each do |line|
    ary.push(line.split.map(&:to_i))
  end

  # 配列 ary の各要素を計算して合計を求める
  result = 0
  ary.each do |a, b|
    if a == b
      result += a * b
    else
      result += a + b
    end
  end

  # 文字列型に変換して末尾に改行を追加する
  result.to_s << "\n"
end

puts solve(STDIN.read)
他の解答例
  • 入力データの受け取りを多重代入で一括処理
  • 整数ペアの計算結果の配列を生成し、sumメソッドで合計を求めて出力
def solve(input_lines)
  _, *lines = input_lines.split("\n")

  result = lines.map { |line|
    a, b = line.split.map(&:to_i)
    a == b ? a * b : a + b
  }.sum

  result.to_s << "\n"
end

puts solve(STDIN.read)

今回のまとめ

繰り返し処理の中でsplitメソッドを使って二次元配列データを受け取り、条件分岐で異なる計算を行いました。

B級問題では二次元配列が多く出題されるのでmapメソッドに慣れておくと良いですね!



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


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






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







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







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







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


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

© 2024 じゃいごテック