4

私はこのPythonコードをCommonLispに変換しようとしています:

for a in xrange(1,1000):
    for b in xrange(a,1000):
        c = (a**2 + b**2) ** 0.5
        s = a + b + c
        if s == 1000:
            return a * b * c

私の最初の試みは:

(loop for a from 1 to 999
      do (loop for b from a to 999
               for c = (sqrt (+ (expt a 2) (expt b 2)))
               for s = (+ a b c)
               until (= s 1000)
               finally return (* a b c))))

これは機能しません。私の仕事は次のとおりですs。1000に達すると、上記の式全体を返し(* a b c)ます。ネストされたループマクロから値を返す方法は?

4

3 に答える 3

11

演算子を使用できます:block名前付きのコードブロックを確立し、ブロックの名前を使用してこのブロックから戻ることができますreturn-fromblockreturn-from

(let (c s)
  (block nested-loops
    (do ((a 1 (1+ a))) ((= a 999))
      (do ((b a (1+ b))) ((= b 999))
        (setf c (sqrt (+ (expt a 2) (expt b 2)))
              s (+ a b c))
        (if (= s 1000)
            (return-from nested-loops (* a b c)))))))

PS、私はここでは使用しませんloop、私はちょうど慣れましたdo

また、http://www.gigamonkeys.com/book/loop-for-black-belts.htmlから

RETURN-FROMを使用して特定のループから戻ることができるようにするには(LOOP式をネストするときに便利です)、名前の付いたloopキーワードを使用してLOOPに名前を付けることができます。名前付き句がループに表示される場合は、それが最初の句である必要があります。簡単な例として、リストがリストのリストであり、それらのネストされたリストの1つでいくつかの基準に一致するアイテムを検索するとします。次のようなネストされたループのペアで見つけることができます。

(loop named outer for list in lists do
     (loop for item in list do
          (if (what-i-am-looking-for-p item)
            (return-from outer item))))
于 2012-12-25T07:29:22.393 に答える
8

Pythonreturnステートメントはループから返されるのではなく、ループが含まれている関数全体から返されます。CommonLispでは、関数は関数と同じ名前の暗黙のブロックを確立します。したがって、次を使用できます。

(return-from function-name (* a b c))

Pythonコードと同等のリターンを実行します。

于 2012-12-25T08:52:23.317 に答える
1

Pythonコードの元の形式を維持しようとしている間、ソリューションは少し調整するだけで機能するはずだと思います

(loop named outer for a from 1 below 1000 do
 (loop for b from a below 1000
    for c = (sqrt (+ (expt a 2) (expt b 2)))
    for s = (+ a b c)
    if (= s 1000) do (return-from outer (* a b c))))

また、中置方程式を入力したい場合は、quicklispから入手できる中置ライブラリを(ql:quickload:infix)で使用し、上記を変更して次のようにすることができます。

(loop named outer for a from 1 below 1000 do
 (loop for b from a below 1000
    for c = #i(sqrt (a^^2 + b^^2))
    for s = #i(a + b + c)
    if (= s 1000) do (return-from outer #i(a * b * c))))
于 2013-12-18T14:48:59.957 に答える