コンテンツへスキップ

【Ruby基礎】AtCoder Beginner Contest 062 A – Grouping

  • by

■はじめに

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

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

■問題

●出典

AtCoder Beginner Contest 062のA問題
https://atcoder.jp/contests/abc062/tasks/abc062_a

●問題文

すぬけ君は、1 から 12 までの整数を下のようにグループ分けしました。 整数 x, y (1 ≤ x < y ≤ 12) が与えられるので、x, y が同一のグループに属しているか判定してください。
グループa:1, 3, 5, 7, 8, 10, 12
グループb:4, 6, 9, 11
グループc:2

●制約

  • x, y は整数である。
  • 1 ≤ x < y ≤ 12

●入力

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

x y

●出力

x, y が同一のグループに属しているならば Yes を、そうでなければ No を出力せよ。

■回答

●愚直に書く

まず、xかyのいずれかが2だったら確実にNoになって、その上でグループaかグループbのいずれかにxとyが両方含まれているかを判別すれば良さそうか。

x, y = gets.split.map(&:to_i)
a = [1, 3, 5, 7, 8, 10, 12]
b = [4, 6, 9, 11]

if x == 2 || y == 2
  puts "No"
else
  if (a.include?(x) && a.include?(y)) || (b.include?(x) && b.include?(y))
    puts "Yes"
  else
    puts "No"
  end
end

遠った!もうちょっとシンプルにしたいが…。

●メソッド化して書く

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

def main
  x, y = read_nums
  a = [1, 3, 5, 7, 8, 10, 12]
  b = [4, 6, 9, 11]
  puts judge_group(a, b, x, y)
end

def judge_group(a, b, x, y)
  if x == 2 || y == 2
  "No"
  else
    if (a.include?(x) && a.include?(y)) || (b.include?(x) && b.include?(y))
      "Yes"
    else
      "No"
    end
  end
end

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

main

通った!

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

なんかもう少しスマートな方法がありそうだけど…。
時間もないのでギブアップ。

●他の方の回答例

最上位の何名かの回答は全然意味がわからない涙。
その下の上位群の回答についても、初め意味がさっぱりわからなかったんだけど、上から順番に見ていったらわかった!
1から12までの整数を「文字列の順番(index)」として捉えて、a グループbグループcグループに振り分けていって、最終的に標準入力のxとyの順番のアルファベットが等しいかどうかで判定できる。
以下のような感じ。

x, y = gets.split.map(&:to_i)
g = "0acababaababa"
puts g[x] == g[y] ? "Yes" : "No"

なるほど…!

●出てきたメソッド等

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

■振り返りなど

頭の柔らかさが足りなかった。
とはいえ新しい種類の問題だった気がするので、新鮮で楽しかった。