Problem31
30分プログラム、その304。Problem31 via ProjectEuler。
イギリスでは硬貨はポンド£とペンスpがあり,一般的な流通ではこれらの8つの硬貨がある.
1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).
以下の方法で£2を作ることが可能である.
1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p
いくらかの硬貨を使って2ポンドを作る方法はいくつあるでしょうか?
よくある両替の問題をちょっと変形させるだけで解ける。Perlでリストを扱うのは面倒なので、組み合せを実際に計算するのではなく、組み合せの数だけを数えるようにした。あと、Perlでちょっと再帰を書くとすぐにDeep recursionの警告がでるのはうざい。
使い方
$ time perl problem31.pl 73682 perl problem31.pl 0.68s user 0.02s system 86% cpu 0.812 total
ソースコード
#! /usr/bin/perl # -*- mode:perl; coding:utf-8 -*- # # problem31.pl - # # Copyright(C) 2008 by mzp # Author: MIZUNO Hiroki / mzpppp at gmail dot com # http://howdyworld.org # # Timestamp: 2008/05/14 22:44:04 # # This program is free software; you can redistribute it and/or # modify it under MIT Lincence. # use strict; use warnings; no warnings "recursion"; sub make_of($@){ my ($target,@coins) = @_; my ($x,@xs) = @coins; # 金額が0 -> 成功 return 1 if($target == 0); # コインが1枚の場合 -> 割り切れるなら使える return ($target % $x) == 0 if(@xs == 0); if($target < $x){ # 目的の金額 < コインの額面 # -> このコインは使えない &make_of($target,@xs); }else{ # コインを使う場合 + コインを使わない場合 &make_of($target-$x,@coins) + &make_of($target,@xs); } } my @coins = (200,100,50,20,10,5,2,1); print make_of(200,@coins),"\n";