LoginSignup
0

More than 3 years have passed since last update.

どこで区切れば合計が同じ数になる???

Last updated at Posted at 2019-05-25

こんにちは!!

今日は以下のような仕様のコードを書いてみました。

仕様
数字の配列が複数与えられます。
各配列の要素をどこかで区切ることによって左右の合計は同じ数になります。
どこで区切れば左右の数の合計が同じ数になるか返すプログラムを作ります。
また、返す際は左側の数字をA,右側の数字をBの文字列にします。

例 input = [
[3, 7, 4, 5, 1],
[6, 9, 1, 8, 8],
[11, 2, 5, 2, 2]
]

output = [
%w(A A B B B),
%w(A A A B B),
%w(A B B B B)
]

こんなの日常的になくない?と思う方もいるかもしれませんが、温かい目で見守って下さると嬉しいです笑

コード

class ArrayNumbers
  def initialize(arr_num)
    @arr_num =  arr_num
  end

  def separate
    @arr_num.map do |row|
      i = 1
      while i <= row.size
        if row[0...i].sum == row[i..-1].sum
          break(("A" * i )+ ("B" * (row.size - i))).chars
        end
        i += 1
      end
    end
  end
end

このようなコードになりました!
初めはmapを使わず、eachメソッドで一文字ずつ配列に入れていたのですが、それだとコードが長くなってしまうのでmapメソッドで最後に評価した値を配列に入れることにしました。
その際while式の戻り値はnilってことを知らなかったので配列の要素が全部nilになっているのを見たときはビックリしました笑
breakに引数を渡せばよかったんですね〜。

個人的には戻り値がもう少しスッキリした書き方があるかな〜と模索していたのですが結局見つかリませんでした泣

追記

@scivola さんからのアドバイスを元にリファクタリングをしてみました!!

class ArrayNumbers
  def initialize(arr_num)
    @arr_num =  arr_num
  end

  def separate
    @arr_num.map do |row|
      1.upto(row.size) { |i|
        if row[0...i].sum == row[i..-1].sum
          break ["A"] * i + ["B"] * (row.size - i)
        end
      }
    end
  end
end

#使用例

input = [
[3, 7, 4, 5, 1],
[6, 9, 1, 8, 8],
[11, 2, 5, 2, 2]
]

p ArrayNumbers.new(input).separate
#=>["A", "A", "B", "B", "B"],
 # ["A", "A", "A", "B", "B"],
 # ["A", "B", "B", "B", "B"]

uptoメソッドは繰り返しとループカウンターを同時に使いたいときにうってつけのメソッドでした!!!
存在自体は知っていたものの活用できていませんでした〜

Array#*は配列を繰り返したい時に使うメソッドです。
これは知らなかった!!!!

勉強になりました!

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