質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1036閲覧

関数外で定義した変数totalを関数内でglobal宣言すると動くが引数に修正するとNoneが返ってくる

opyon

総合スコア1009

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/10/12 09:12

編集2018/10/12 10:38

##清書(最終)

Python3

1def coin_sums2(remainder, coin): 2 if coin < 0: 3 return 1 4 n = remainder // coins[coin] 5 total2 = 0 6 for i in range(n + 1): 7 total2 += coin_sums2(remainder - i * coins[coin], coin - 1) 8 return total2 9 10 11coins = [2, 5, 10, 20, 50, 100, 200] 12ans = coin_sums2(200, len(coins) - 1) 13print(ans)

##追記(18:40)
回答頂いた後ものをヒントに修正したらこれで動きました。

Python3

1def coin_sums2(remainder, coin,total2=0): 2 if coin < 0: 3 return total2 + 1 4 n = remainder // coins[coin] 5 for i in range(n + 1): 6 total2 += coin_sums2(remainder - i * coins[coin], coin - 1) 7 return total2 8 9coins = [2, 5, 10, 20,50, 100, 200] 10ans = coin_sums2(200, len(coins)-1) 11print(ans)

####参考課題
ProjectEuler Problem 31 : Coin sums
日本語訳

#現状
環境:Python3.7.0

coin_sums
関数の外で定義したtotal変数をインクリメントすると最後にprint(total)で正解が出力されています。

coin_sums2
少し修正し戻り値を受け取って出力させたい。
その為にtotal変数の代わりに初期値0の引数を渡して最終的な戻り値をans変数に代入してprint(ans)で出力させたい。
しかし結果はNoneでした。

#知りたいこと
引数の渡し方や戻り値の受け取り方のどこかで間違っているのだと思うのですが堂々巡りしていて時間だけが過ぎています。
正常に動くにはどうすれば良いかヒントなどご教示頂けると助かります。

#coin_sums

python3

1def coin_sums(remainder, coin): 2 global total 3 if coin < 0: 4 total += 1 5 return 6 n = remainder // coins[coin] 7 for i in range(n + 1): 8 coin_sums(remainder - i * coins[coin], coin - 1) 9 10coins = [2, 5, 10, 20,50, 100, 200] 11total = 0 12coin_sums(200, len(coins)-1) 13print(total) 14#73682

#coin_sums2

python3

1def coin_sums2(remainder, coin,t): 2 total2 = t 3 if coin < 0: 4 total2 += 1 5 return total2 6 n = remainder // coins[coin] 7 for i in range(n + 1): 8 coin_sums2(remainder - i * coins[coin], coin - 1,total2) 9 10coins = [2, 5, 10, 20,50, 100, 200] 11ans = coin_sums2(200, len(coins)-1,0) 12print(ans) 13#None

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

けっきょくtotalは作らなくても良さそうでした。

python

1def coin_sums2(remainder, coin): 2 if coin < 0: 3 return 1 4 else: 5 n = remainder // coins[coin] 6 results = [] 7 for i in range(n + 1): 8 results.append(coin_sums2(remainder - i * coins[coin], coin - 1)) 9 return sum(results) 10 11coins = [2, 5, 10, 20,50, 100, 200] 12ans = coin_sums2(200, len(coins)-1) 13print(ans) 14

下の方法だと元のコードのロジックを活かせます。

python

1def coin_sums2(remainder, coin): 2 total = 0 3 def coin_sums_i(remainder, coin): 4 nonlocal total 5 if coin < 0: 6 total += 1 7 return 8 n = remainder // coins[coin] 9 for i in range(n + 1): 10 coin_sums_i(remainder - i * coins[coin], coin - 1) 11 12 coin_sums_i(remainder, coin) 13 return total 14 15coins = [2, 5, 10, 20,50, 100, 200] 16ans = coin_sums2(200, len(coins)-1) 17print(ans)

投稿2018/10/12 09:20

編集2018/10/12 09:45
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

opyon

2018/10/12 09:27

なるほど、感激です。 多分自分で考え続けても答えは出なかったと思いました。 動かしてみて勝手な解釈ですが省略可能な引数ということでしょうか? 理解出来ているかまだ不安なので定型パターンとしてメモしておきます。 ありがとうございました。
hayataka2049

2018/10/12 09:29

ごめんなさい、適当にやってたら結果が合ったので投げちゃいましたが、たぶんうまくないところがあると思います。修正するので少しお時間を・・・
opyon

2018/10/12 09:34

関数の引数が4つで、初期値で渡す引数が3つで動いているのが不思議だなと思っていましたがそのことでしょうか?
hayataka2049

2018/10/12 09:43

tは使ってなかったし、よく見たら色々削れました
opyon

2018/10/12 09:43

自分でも修正してみたら動きました。 初回のみtotal=0が機能してそれ以後はtotal+=で加算され最後にreturn totalで戻ってくるということかと解釈しました。
opyon

2018/10/12 09:50

すみません、違う書き方だったようですね。確認します。 私が書いた追記は偶然動いてるだけなのでしょうか?
hayataka2049

2018/10/12 10:03 編集

return total2 + 1 のときtotal2は常に0なので、1を返せば良く、そうすると引数のデフォルト値として設定する必要もないのでそれは外し、下のforは単に結果の総和を出せば良い……と考えると私のコードになります
opyon

2018/10/12 10:33

results = [] for i in range(n + 1): results.append(coin_sums2(remainder - i * coins[coin], coin - 1)) return sum(results) 最初のreturnは常に 1 として、その後は書き方の違いで等価のようですね。 どちらが良いのか判断に迷いますが両方メモしておきます。 ありがとうございました。 total2 = 0 for i in range(n + 1): total2 += coin_sums2(remainder - i * coins[coin], coin - 1) return total2
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問