TL;DR
コード
class BonusDrink
def self.total_count_for(amount)
new(amount).total_count
end
def initialize(drinks, empties = 0, drunks = 0)
@drinks = drinks
@empties = empties
@drunks = drunks
end
def total_count
until @drinks.zero?
drink
exchange
end
@drunks
end
private
def drink
@empties += @drinks
@drunks += @drinks
@drinks = 0
self
end
def exchange
bonus, @empties = @empties.divmod(3)
@drinks += bonus
self
end
end
簡単な説明
方針としては、【ジュースの数】【空きビンの数】【飲んだ本数】の状態をインスタンス変数として保持し、【飲んだ時の状態の変化】と、【空き瓶を交換した時の状態の変化】をメソッドにしました。
-
@drinks
が【ジュースの数】です。 -
@empties
が【空きビンの数】です。 -
@drunks
が【飲んだ本数】です。 - ジュースを飲むと、【空きビンの数】と【飲んだ本数】が【ジュースの数】だけ増え、【ジュースの数】は0になります。これが
drink
メソッドです。 - 空きビンを交換すると、【空きビンの数】を3で割った商の数がボーナスとしてもらえるジュースの数となり、その分【ジュースの数】が増えます。また、【空きビンの数】は3で割った余りになります。これが
exchange
メソッドです。 - そして、
drink
とexchange
を繰り返していくと、【空きビンの数】が少なくなって、exchange
してもボーナスのジュースがもらえず、【ジュースの数】が0のままになってしまいます。これ以上ジュースは飲めませんから、これが最終の状態で、この時点での【飲んだ本数】が答えになります。これがtotal_count
メソッドです。 - 問題は、クラスメソッドを求めているようなので、
BobusDrink.total_count_for
の中で、インスタンスを作成して、total_count
を呼び出しました。