2

itertools.count 関数に問題があり、その機能がよくわかりません。以下のコードでProject Euler の問題 2を達成できると思います。

単純な while ループでこれを記述できることはわかっていますが、リスト内包表記でそれを行う方法はありますか? このコードは、count() で無限大になると推測されるため、フリーズするだけです。x > MAX の後に停止することを望んでいましたが、それが起こらないことはわかっています。以下のようなジェネレーター式でカウントを停止する方法はありますか?

def fib(n):
    if (n <= 1): return 1
    else: return fib(n-1) + fib(n-2)


MAX = 4000000

infiniteFib = (fib(x) for x in count())

s = (x for x in infiniteFib if x < MAX and x % 2 == 0)

print sum(s)
4

5 に答える 5

7

使用できますtakewhile

>>> from itertools import count, takewhile, imap
>>> sum(x for x in takewhile(lambda x: x < 4000000, imap(fib, count())) if x % 2 == 0)
4613732
于 2012-12-10T23:27:51.060 に答える
5

infiniteFib要素の生成を停止するタイミングをジェネレーターに伝える必要があるだけです。itertoolsこれに役立つ多くの便利なメソッドを提供します。

less_than_max = itertools.takewhile(lambda x: x<MAX, infiniteFib))
even = itertools.ifilter(lambda x: x%2==0, less_than_max)
print sum(even)

によって生成されたすべての数値のジェネレーターを取得し、infiniteFib返される数値が より大きくなるまで続けMAXます。次に、偶数のみを選択して、そのジェネレーターをフィルター処理します。最後に、結果を合計できます。

于 2012-12-10T23:28:58.147 に答える
3

どうですか:

def fib():
    a, b = 1, 1
    while True:
        yield b
        a, b = b, a+b

sum(f for f in itertools.takewhile(functools.partial(operator.ge, 4000000), fib()) if f % 2 == 0)

または、パリティ チェックをジェネレーターにプッシュします。

def even_fib():
    a, b = 1, 1
    while True:
        if b % 2 == 0: yield b
        a, b = b, a+b

sum(itertools.takewhile(functools.partial(operator.ge, 4000000), even_fib()))
于 2012-12-10T23:33:08.870 に答える
0

を使用した別のソリューションを次に示しますtakewhileが、再帰的ではありません。fib再帰的なソリューションでは、n ごとに n 未満のすべての s を計算する必要があるため、非常に遅くなります。

def fib_gen(only_even=False):
    one = 1
    if not only_even:
        yield one
    two = 1
    if not only_even:
        yield two
    while True:
        next = one + two
        one = two
        two = next
        if only_even:
            if next % 2 == 0:
                yield next
        else:
            yield next

list(itertools.takewhile(lambda x: x < 4000000, fib_gen()))
于 2012-12-10T23:33:11.213 に答える
0

ええ、count()ただ続けてください、それはあなたが望んでいることではありません。リスト内包表記/イテレータ式には、柔軟な終了条件がありません (ただし、 @DSM の を使用したソリューションを参照してくださいtakewhile)。

私はただ使うのが好きですwhile

Euler 2に対する私の古い答えは次のとおりです。

def SumEvenFibonacci(limit):
        x = y = 1
        sum = 0
        while (sum <= limit):
                sum += (x + y)
                x, y = x + 2 * y, 2 * x + 3 * y
        return sum

ce = SumEvenFibonacci(4000000)
print ce
于 2012-12-10T23:20:31.350 に答える