LoginSignup
0
0

More than 1 year has passed since last update.

[初学者/At_Corder] A.Cookie_Exchangesを解いてみた

Last updated at Posted at 2022-03-13

[初学者/At_Corder] A.Cookie_Exchangesを解いてみた

目次

  • 概要
  • 開発環境
  • 解答と説明
  • まとめ

概要

A.Cookie_Exchangeの問題です。
[2022/03/14] @scivola 様からのコメント内容にて、ご教示いただいた内容を解答に反映しております。

開発環境

  • Ruby 2.6.3
  • Visual Studio Code
  • Ubuntu 20.04.3

解答と説明

問題文は下記のサイトにて、ご覧いただけます。

解答
cokkie_exchange.rb
a,b,c = gets.split.map(&:to_i)

arr = [a,b,c]
count = 0

if arr.uniq.one? && arr.all?(&:even?)
	puts -1
else
  while arr.all?(&:even?)
    arr = arr.rotate.zip(arr.rotate(2)).map{ |i| i.sum / 2 }
    count += 1
  end
  puts count
end
説明

<流れ>

  • 入力された値をa,b,cに代入。
  • 最終的に出力する実行回数をcountとして定義。
  • (if)a=b=cかつすべて偶数の時は、無限処理になるため、繰り返し処理をせずに、-1を表示。
  • (else)すべて偶数の時は、クッキーを分ける処理を繰り返し、奇数が含まれる時は、countを出力。

上記流れをコメントとして、実際のコードに付け加えると下記のようになります。

説明コメント付き
# 入力された値をa,b,cに代入。
a,b,c = gets.split.map(&:to_i)

arr = [a,b,c]

# 最終的に出力する実行回数をcountとして定義。
count = 0

# a=b=cかつすべて偶数の時は、無限処理になるため、繰り返し処理をせずに、-1を表示。
if arr.uniq.one? && arr.all?(&:even?)
	puts -1
else
# すべて偶数の時は、クッキーを分ける処理を繰り返し、奇数が含まれる時は、countを出力。
  while arr.all?(&:even?)
    arr = arr.rotate.zip(arr.rotate(2)).map{ |i| i.sum / 2 }
    count += 1
  end
  puts count
end

<メソッド説明>

  • 入力された値の取得
    空白区切りの取得に、splitを用い、
    すべてIntegerで取得するために、a,b,cそれぞれに、to_iをmapメソッドにて、処理しています。
入力された値の取得
# a,b,c = とすると、一度に代入できます。
a,b,c = gets.split.map(&:to_i)
  • a=b=cの判定
    a,b,cはIntegerのため、配列.uniq.one? を用いています。
a=b=cの判定
arr.uniq.one?
  • 偶数の判定
    all?メソッドを用いて、配列内の要素すべてに対して、偶数であるか(even?メソッド)を判定しています。
偶数の判定
arr.all?(&:even?)
  • arr.rotate.zip(arr.rotate(2)) とは
    rotateとzipを用いることで、それぞれの人ごとに必要なクッキーの個数を配列にすることが出来ます。
arr.rotate.zip(arr.rotate(2)) とは
arr.rotate.zip(arr.rotate(2))
# (例)4 12 20と入力したとき、
# =>[[12, 20], [20, 4], [4, 12]]
  • クッキーを分ける処理
    前述の配列化したクッキーの個数を、配列ごとにsumで合計を算出し、2で割っています。
クッキーを分ける処理
arr = arr.rotate.zip(arr.rotate(2)).map{ |i| i.sum / 2 }
# (例)4 12 20と入力したとき、
# arr.rotate.zip(arr.rotate(2)) => [[12, 20], [20, 4], [4, 12]]
# [[12, 20], [20, 4], [4, 12]].map{ |i| i.sum / 2 } => (処理イメージ)[[(12+20)/2],[(20+4)/2],[(4+12)/2]]

# Ruby 2.7以上の方は、arr[_1]が使用できるため、下記でも可。
# (arr[_1]とは、何者だろうと思われた方は、コメントのscivola 様の解説をご覧ください。)
arr = arr.rotate.zip(arr.rotate(2)).map{ _1.sum / 2 }

まとめ

ざっくりと解答をまとめてみました。
より良いコードになるよう、アドバイスいただけると、嬉しいです!

参考サイト

0
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0