###まとめ
動くか動かないかの切り分けは完全には出来ていませんが特にPythonのVer差でもOS差でも無いような気がします。
動かなかった環境は以下のとおりです。
全てNG
・OS:Windows10 Home 64bit
・Python:3.6.6 , 3.7.0
・IDE:Eclipse4.8 , Jupyter Notebook
・コマンドライン
その他コメントより
NG
・3.4.3 on Windows8.1/64bit
OK
・3.7.0
@hayataka2049さんの回答より
Python: What is the hard recursion limit for Linux, Mac and Windows? - Stack Overflow
Windows版Pythonの再帰呼び出し制限 - kusano_kの日記
sys.setrecursionlimit(1024*1024)
で再帰呼び出しの深さ制限を変更できるけど、Pythonのスタックサイズが足りないらしく、Pythonが不正終了する。Windowsの場合、新しく作成されるスタックのサイズを
thread.stack_size(12810241024)
で変更できる。
@LouiS0616さん回答より
@functools.lru_cache(maxsize=128, typed=False)
関数をメモ化用の呼び出し可能オブジェクトでラップし、最近の呼び出し最大 maxsize 回まで保存するするデコレータです。高価な関数や I/O に束縛されている関数を定期的に同じ引数で呼び出すときに、時間を節約できます。
フィボナッチ数列絡みの問題を再帰で実装する際は、
functools.lru_cache でメモ化するとトラブルが少ないです。
どちらのコードも試してみて動作確認出来ました。
個人的にはimportと@デコレータ追記だけなのでこちらが実用的かとは思います。
追記補足:
但し質問時の元のコードのままで@デコレータ追記だけでは動きませんでした。
@LouiS0616さん回答のように関数を分割すると動きました。
GitHub 修正後のコード qa151136_ok2.py
from functools import lru_cache # @lru_cache(maxsize=None) @lru_cache(maxsize=8) def fibo(n):
Pythonで再帰階層が深くなる場合には気をつけるという教訓にもなりました。
回答やコメントなどでの情報提供ありがとうございました。
###知りたいこと
エラーも結果も出力されない原因が知りたいです。
原因が分かる方いらっしゃればご教示お願いします。
###起きている現象
Problem 25 : 1000-digit Fibonacci number
上記問題を解くのに下記プログラムでN=1000
を入力すると正解が出力されるはずなのですが、
関数の再帰処理を使い入力値をN=823
以上にすると結果もエラーも表示されずに終了してしまいます。
###実行環境
Windows10
Python3.7.0
Python3
1import sys 2import math 3# 再帰回数の上限 4# sys.setrecursionlimit(2100000000) 5sys.setrecursionlimit(10000) 6 7def fibo2(n_1, n_2, count): 8 n = n_1 + n_2 9 count += 1 10 if n >= target: 11 return count 12 return fibo2(n, n_1, count) 13 14# N = 1000で問題を解きたいのに 15# N = 823以上になると結果が表示されない 16# N = 823 17N = 822 18target = 10 ** (N-1) 19print(fibo2(1, 1, 2)) 20 21# 検算 22# N = 3 23# 12
##試したこと
whileループで書き換えると結果が出るので桁数の問題では無いことは確認済みです。
Python3
1def fibo1(target): 2 a, b = 1, 1 3 cnt = 2 4 target -= 1 5 while b < 10 ** (target): 6 cnt += 1 7 a, b = b, a + b 8 return cnt 9 10target = 1000 11print(fibo1(target)) 12# 出力結果 13# 4782
最初は再帰回数の上限でエラーが出たので調べたら上限設定を変更可能と知ったので変更済みです。
import sys # 再帰回数の上限 # sys.setrecursionlimit(2100000000) sys.setrecursionlimit(10000)
回答3件
あなたの回答
tips
プレビュー