3

ピタゴラスのトリプレット (以下のコード) を計算したいのですが、3 つの for ループを使用せずに無限に計算するにはどうすればよいですか? 何らかの方法で for ループを使用できますか? ありがとう。

import math

def main():
    for x in range (10000, 1000):
        for y in range (10000, 1000):
            for z in range(10000, 1000):
                if x*x == y*y + z*z:
                    print y, z, x
                    print '-'*50

if __name__ == '__main__':
    main()  
4

12 に答える 12

8

通常、できません。3 つの変数、3 つのループ。

しかし、誰も指摘しなかったように、これは特殊なケースです。この問題は 2 つのループで解決できます。

また、y, z と z, y をチェックしても意味がありません。

ああ、そしてrange(10000, 1000) = []

import math

for x in range(1, 1000):
  for y in range(x, 1000):
      z = math.sqrt(x**2 + y**2)
      if int(z) == z:
        print x, y, int(z)
        print '-'*50
于 2009-02-25T21:52:06.447 に答える
4

必要なループは 2 つだけですmath.sqrt(x*x+y*y)。 が整数かどうかを確認するだけです。そうであれば、ピタゴラス数を発見したことになります。

私は Python を初めて使用するので、何が機能するのかわかりません。range(10000, 1000)どこで開始し、どこで停止しますか? 足し算は可換であるという事実により、y開始の範囲を固定するのではなく、実行時間を半分にすることができるためです。x

編集: この答えは私が得ていたものであり、Pythonをもっと知っていれば書いていたものです。

于 2009-02-25T21:55:26.967 に答える
2

これは、反復子を使用して、そのようなすべてのトリプルを順番に生成する効率的なバージョンです。ここでのコツは、すべての N について、合計が N になる (x,y) ペアのセットを繰り返し処理することです。

インポート数学
インポート itertools

def all_int_pairs():
    「正の整数のすべてのペアを生成する」
    n の itertools.count(1):
        xrange(1,n/2+1) の x の場合:
            収量 x,nx

for x,y in all_int_pairs():
    z = math.sqrt(x**2 + y**2)
    int(z) == z の場合:
        x、y、int(z)を出力
        印刷 '-'*50
于 2009-02-26T01:04:36.060 に答える
2

特に大きな範囲を試したい場合は、代わりにxrangeを使用するとメモリの使用量が少なくなります。range

于 2009-02-25T22:39:31.387 に答える
1

同じアルゴリズムを使用して (より良いアプローチについては他の回答を参照してください)、 itertools.count を使用して永久に実行されるループを取得できます。

import itertools

for x in itertools.count(1):
    for y in xrange(1, x):
         for z in xrange(1, y):
              if x*x == y*y + z*z:
                  print x, y, z
于 2009-02-25T23:13:41.040 に答える
1

これは Can Berk Guder の回答と同じですが、楽しみのためにジェネレーターとして実行されます。ここでネストされたループではあまり役に立ちませんが、多くの場合、よりクリーンなソリューションになる可能性があります。関数は結果を生成します。後で取得する数について心配します。

import math

def triplets(limit):
    for x in range(1, limit):
        for y in range(x, limit):
            z = math.sqrt(x**2 + y**2)
            if int(z) == z:
                yield x, y, int(z)

for x, y, z in triplets(10):
    print x, y, z
    print "-" * 50
于 2009-02-25T22:58:04.103 に答える
1

最も効率的ではありません (Python は 10 億のタプルを持つ配列を作成します) が、これは単一のループです:

for x, y, z in [(x, y, z) for x in range(10000, 11000) for y in range(10000, 11000) for z in range(10000, 11000)]:
    if x*x == y*y + z*z:
        print y, z, x
        print '-'*50

または、 Christian Wittsが示唆するように、

for x, y, z in ((x, y, z) for x in xrange(10000, 11000) for y in xrange(10000, 11000) for z in xrange(10000, 11000)):
    if x*x == y*y + z*z:
        print y, z, x
        print '-'*50

(Python >= 2.4 と仮定) は、10 億タプル配列を構築する代わりにジェネレーターを使用します。

いずれにせよ、このようなコーディングはすべきではありません... ネストされたループを使用した最初のコードはより明確です。

于 2009-02-25T22:13:33.600 に答える
0

無限大には少なくとも3つのループが必要です。何かを柔軟にするには、大量のループが必要です。この例は、Project EulerProblem9以降のソリューションです。

#!/usr/bin/env python

def fcount(start=1):
    n = float(start)
    while True:
        yield n
        n += 1

def find_triples():
    for c in fcount():
        for b in fcount():
            if b > c:
                break
            for a in fcount():
                if a > b:
                    break
                if a ** 2 + b ** 2 == c ** 2:
                    yield (a, b, c)

def triples_by_sum(targetsum):
    for a, b, c in find_triples():
        if a + b + c == targetsum:
            yield a, b, c
        if c > targetsum:
            break

if __name__ == '__main__':
    # Finds multiple triples
    for a, b, c in triples_by_sum(252):
        print a, b, c
    # Finds single triples
    a, b, c = triples_by_sum(1000).next()
    print a, b, c
    # Goes forever
    for a, b, c in find_triples():
        print a, b, c
于 2009-02-26T02:52:46.863 に答える
0

無限に数えたいなら..

ゼロからカウントして停止しないジェネレーター関数を作成し、その上で for ループを使用します。

def inf():
   i = 0
   while True:
     yield i
     i = i + 1

for i in inf():
    print i  # or do whatever you want!

そのような組み込み関数がすでにあるかどうかはわかりません

于 2009-02-25T23:08:12.237 に答える
0

すでに投稿されているものに加えて、人々は 3 つのコレクションに対して 3 つのループを期待するでしょう。それ以外のものは非常に混乱を招く可能性があり、追加の利点はありません.

于 2009-02-25T21:55:15.453 に答える
0

代わりに itertools.product を使用するのはどうですか?

# range is [10000, 1000)
for x, y, z in itertools.product(range(10000, 1000, -1), repeat=3): 
    if x * x == y * y + z * z:
        print(y, z, x)

少し最適化すると:

for x, y, z in itertools.product(range(10000, 1000, -1), repeat=3):
    if y >= x or z >= x or x >= (y + z) or z < y:
        continue
    if x * x == y * y + z * z:
        print(y, z, x)

編集:ここでproductは、複数の for ループの代わりに使用する方法を示します。また、上記の投稿でより効率的な方法を見つけることができます。

于 2011-08-04T07:22:53.783 に答える