例: コインチェンジ遊び

S を正の数の有限集合としましょう。 解決したい問題とは、与えられた整数 x を、S から選択した正の数の倍数の和として表現する、異なる方法の数を見つけることです。 S 中のそれぞれの数をコインの額面に見立てると、 この問題は、与えられた値 x をコインの集合の和で表わす異なる方法がいくつあるか調べることになります。 この数を cc(S, x) で表わすと、関数 cc は次の特性を持ちます:

次の実装では、S を 1, 5, 10, 25 からなる集合に設定しています。

// typedef int4 = (int, int, int, int) // val theCoins = (1, 5, 10, 25): int4 // fun coin_get (n: int): int = ( if n = 0 then theCoins.0 else if n = 1 then theCoins.1 else if n = 2 then theCoins.2 else if n = 3 then theCoins.3 else ~1 (* erroneous value *) ) (* end of [coin_get] *) // fun coin_change (sum: int): int = let fun aux (sum: int, n: int): int = if sum > 0 then (if n >= 0 then aux (sum, n-1) + aux (sum-coin_get(n), n) else 0) else (if sum < 0 then 0 else 1) // end of [aux] in aux (sum, 3) end // end of [coin_change] //

関数 coin_change の本体の中で定義されている補助関数 aux は上記で述べた cc 関数に該当します。 1000 に適用すると、関数 coin_change142511 を返します。

この章で紹介したコード全体と追加のテストコードは オンライン から入手できます。