2017-11-16 19 views
1

Pythonの関数プログラミング機能を使ってwhileループを構築したいが、今までは失敗している。Functional Programming Python:1〜20の各数字で割り切れる最小の数字

私が達成したことは、1から20までの各数字で割り切れる最小の数を計算するコードの平和です。しかし、それは関数型プログラミング機能を多く使用しているように見えません。これは、これは多くの理由のための非functialで20

def byYmult(x, y): return x % y == 0 
def first20div(): 
    i=0 
    for y in range(1,20): 
     i += byYmult(x, y) 
    return i >= 20 

def while_block(): 
    global x 
    if first20div(): 
     print(x) 
     return 1 
    else: 
     x += 1 
    return 0 

x = 0 
while_FP = lambda: ((not first20div()) and while_block()) or while_FP() 
while_FP() 
+2

あなたは既に一度この質問をしました。しかし、エラーはそれ自身について語ります。反復するすべての要素に対して再帰を実行します。解決策は> 1Gです。スタックが増えています。グローバルを使用することは、実際にはほぼ確実に機能しないことに注意してください。関数型プログラミングは通常、* immutable *データで動作するためです。 –

+0

@WillemVanOnsem私はあなたの答えを理解していません。再帰を実行して私が探している数を増やし、反復(forループ)は条件付き検査部分(つまり、再帰を止めなければならないかどうかを理解する)です。 –

+0

どこに再帰がありますか? –

答えて

5

に限定されるべきである場合でも

"RuntimeError: maximum recursion depth exceeded" at the line of the incrementation of "i";

::そしてまた、以下のように私にエラーを与える

  1. あなたは渡したり、関数を返さないでください。
  2. 下部に名前付きラムダ式を作成するだけですが、これは通常の非Pythonのとみなされます。
  3. 通常、機能プログラミングとはデータを変更しないことを意味しますが、ここでは更新するglobal xを定義します。
  4. 一部のグローバルでも機能していないとみなされます。すべてのデータを関数に渡す必要があります。

このように多くの機能があります。さらに、あなたが記述するアルゴリズムはあまり最適ではありません。最終的に私たちが幸運になるまで数を推測し続けるブルートフォースアプローチを実行するのではなく、より良いアプローチは、数値1.24のの最小公倍数(LCM)を計算することです。

まず定義することができる - 機能的な方法で - まず最大公約数(GCD)を計算することにより、LCMを計算することができ、これはEuclidean Algorithmによって行うことができます。私たちのために幸運、それはmathパッケージに既にある:

from math import gcd 

今LCMは次のとおりです。

def lcm(a,b): 
    return (a*b)//gcd(a,b) 

3つの以上の数字のLCMは、最初の2つの数のLCMを計算することにより算出することができますそして、より正式に第3の数、またはでLCMに最初の引数として渡し:

lcm(x,y,z) == lcm(lcm(x,y),z) 

これはからreduceを使用して行うことができ:

from functools import reduce 

def lcm_multiple(xs): 
    return reduce(lcm, xs) 

を、今、私たちはそれをrange(2,20)オブジェクトを渡すことによって、答えを計算することができます。

answer = lcm_multiple(range(2, 20)) 

または全額を:

from math import gcd 
from functools import reduce 

def lcm(a,b): 
    return (a*b)//gcd(a,b) 

def lcm_multiple(xs): 
    return reduce(lcm, xs) 

answer = lcm_multiple(range(2, 20)) 
+0

これは素晴らしいことです。大いに感謝する。 –

関連する問題