最近見かけたブログの記事。
cf. Haskell/Clojureで数学パズル:コインの両替 – Programmer’s Note
同じような問題はずっと前に Haskell でやったことがあるんだけど、今回は Go でやってみる。はじめに思い付いたのはリンク記事の後半に出てくる再帰を使ったほうなんだけど、まずはリンク記事と同じ順で for
を使ったやり方で。
package main import ( "fmt" ) func main() { fmt.Println(change_coin(1000, 15)) } func change_coin(money, max_coins int) int { patterns := 0 for m10 := 0; m10 <= max_coins; m10++ { for m50 := 0; m50 <= max_coins; m50++ { for m100 := 0; m100 <= max_coins; m100++ { for m500 := 0; m500 <= max_coins; m500++ { if m10 + m50 + m100 + m500 <= max_coins && 10 * m10 + 50 * m50 + 100 * m100 + 500 * m500 == money { patterns += 1 } } } } } return patterns }
ああ、ネストした for
文が美しくない!!
で、こっちが再帰を使ったほう。
package main import ( "fmt" ) func main() { coins := []int{ 10, 50, 100, 500 } fmt.Println(change_coin2(1000, coins, 15)) } func change_coin2(money int, coins []int, max_coins int) int { if money == 0 { return 1 } else if len(coins) == 0 { return 0 } else if max_coins == 0 { return 0 } else { patterns := 0 for use := 0; use <= max_coins; use++ { patterns += change_coin2(money - coins[0] * use, coins[1:], max_coins - use) } return patterns } }
だいぶマシだけど else if
がなあ。改めて Haskell のパターンマッチの美しいことを思い知る。