Persisting Hashes in Ruby

213 views Asked by At

I am trying to solve a simple Ruby Quiz problem and having trouble working with hashes. When I make the wallet a regular variable the loop has no idea bout the variable wallet and when I make it an @wallet the merge is not persisted when returned after the loop.

I have also tried merge! which collect all the garbage and keeps data from previous test.

class Coins
  COINSTAR = { :H=>50,:Q=>25,:D=>10,:N=>5,:P=>1 }

  def self.make_change(value)
    return {} if value == 0

    COINSTAR.each do |k,v|
      wallet = Hash.new
      if value >= v
        wallet.merge(k=>value / v)
        value = value - (v * (value % v))
      end
    end
    wallet
  end
end

#Test run
Coins.make_change(26)
Coins.make_change(91)
Coins.make_change(1)

#=>returns

# {:P=>1, :Q=>1}
# {:P=>1, :Q=>1, :H=>1}
# {:P=>1, :Q=>1, :H=>1}

Any ideas on how to persist the hash without collecting data from previous test?

1

There are 1 answers

1
Joseph On BEST ANSWER

To get this to work, you need to fix 3 problems.

First, as ymonad notes, move wallet = Hash.new before the each loop.

Second, change merge to merge!.

Third, change value = value - (v * (value % v)) to value = value % v.

The first change is needed to move wallet to the scope of the method def self.make_change rather than the scope of the each loop.

The second change is needed as you do want to persist the data through all iterations of the each loop (so you get half dollars, quarters, dimes, nickels, and pennies added).

The third change is needed to make sure value equals the number of coins remaining (e.g, value is 91, v is 50, 91 % 50 = 41 but 91 - (50 * (91 % 50)) = 91 - (50 * 41) = (91 - 2050) = -1959).