お預かり金額 と 釣り銭
お預かり金額(deposit)と値段(price)を与えると、最小枚数の釣り銭構成を返すプログラム。
def change_pattern(deposit, price) return [0] if deposit == price fail if deposit < price currencies = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 100000] # 2000円札は嫌がられるので使わない change = deposit - price max_count = change / currencies.min (1..max_count).map{ |count| currencies.repeated_combination(count).map{ |pattern| return pattern if pattern.inject(:+) == change } } end p change_pattern(1000, 541)
重複あり組合せを探索木にして、少ない枚数組合せから順に取り出しながら、金額一致まで幅優先探索しています。
割り算と再帰で書くのが定番ですが、何となく幅優先探索で書いてみたかったので。
重複あり組合せをどう作ろうかと悩んでいたのですが、標準関数にrepeated_combination があって助かりました。
Ruby べんり。