コンテンツへスキップ

【Ruby基礎】AtCoder Beginner Contest 067 A – Sharing Cookies

■はじめに

Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。
基本的にはAtCoderというプログラミングコンテスト(競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)

(5/23時点の方針)
メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。

(2022/10/17時点の方針)
まず、A問題70問、B問題30問までを目指す。

■問題

●出典

AtCoder Beginner Contest 067のA問題
https://atcoder.jp/contests/abc067/tasks/abc067_a

●問題文

すぬけくんは 3 匹のヤギにクッキーを渡したいです。

すぬけくんは A 枚のクッキーが入った缶と、B 枚のクッキーが入った缶を持っています。 すぬけくんは A,B,A+B のいずれかの枚数のクッキーをヤギたちに渡すことができます。

3 匹のヤギが同じ枚数ずつ食べられるようにクッキーを渡すことが可能かどうか判定してください。

●制約

  • 1≤A,B≤100
  • A,B はいずれも整数

●入力

入力は以下の形式で標準入力から与えられる。

A B

●出力

3 匹のヤギが同じ枚数ずつ食べられるようにクッキーを渡すことが可能ならば Possible と、そうでなければ Impossible と出力せよ。

■回答

●愚直に書く

Aが3の倍数、もしくはBが3の倍数、もしくはA+Bが3の倍数ならPossibleということかな。

a, b = gets.split.map(&:to_i)
if a % 3 == 0
  puts "Possible"
elsif b % 3 == 0
  puts "Possible"
elsif (a + b) % 3 == 0
  puts "Possible"
else
  puts "Impossible"
end

通った!
なんかもうちょっとスマートにしたい感じはある。

●リファクタリング/別アプローチ

elseifをやめて、ifの中に||で繋いだ。

a, b = gets.split.map(&:to_i)
if a % 3 == 0 || b % 3 == 0 || (a + b) % 3 == 0
  puts "Possible"
else
  puts "Impossible"
end

通った!

ということは三項演算子にしても良いか。

a, b = gets.split.map(&:to_i)
puts (a % 3 == 0 || b % 3 == 0 || (a + b) % 3 == 0) ? "Possible" : "Impossible"

通った!

●メソッド化して書く

メソッドを作る練習のために、あえてそういう書き方をする。

def main
  a, b = read_nums
  puts is_possible?(a,b)
end

def is_possible?(a,b)
  if a % 3 == 0 || b % 3 == 0 || (a + b) % 3 == 0
    "Possible"
  else
    "Impossible"
  end
end

def read_nums
  gets.split.map(&:to_i)
end

main

通った!

●他の方の回答例

標準入力を取るタイミングで%3することで、後で%3を3回書く手間を省くというのはなるほどと思った。

あと、最上位回答の方の考え方が面白かったのでメモ。
条件をa*b*(a+b)%3==0にしている。aba+bを全部かけて%3した余りが0になるということは、すなわちaba+bのいずれかが3の倍数であるということ。なるほど〜!!面白い。

●出てきたメソッド等

公式リファレンスを見る訓練。

今回は無し。

■振り返りなど

今回は算数的な考え方の勉強になった。