コインの両替

最近見かけたブログの記事。

cf. Haskell/Clojureで数学パズル:コインの両替 – Programmer’s Note

同じような問題はずっと前に Haskell でやったことがあるんだけど、今回は Go でやってみる。はじめに思い付いたのはリンク記事の後半に出てくる再帰を使ったほうなんだけど、まずはリンク記事と同じ順で for を使ったやり方で。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
}
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 }
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 文が美しくない!!

で、こっちが再帰を使ったほう。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
}
}
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 } }
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 のパターンマッチの美しいことを思い知る。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください