1

次の形式を取る、Scheme で可変長関数を定義する必要があります。(define (n-loop procedure [a list of pairs (x,y)])ここで、ペアのリストは任意の長さにすることができます。

各ペアは、下限 (含む) と上限 (含まない) を指定します。つまり、次の関数呼び出し: は以下(n-loop (lambda (x y) (inspect (list x y))) (0 2) (0 3))を生成します。

(list x y) is (0 0)
(list x y) is (0 1)
(list x y) is (0 2)
(list x y) is (1 0)
(list x y) is (1 1)
(list x y) is (1 2)

さて、私は以前このトピックに投稿したことがあり、素晴らしく助けられました. しかし、私は従うべき新しいガイドラインを与えられました。ソリューションは、ネストされたマップのみを使用して見つけることができます。

これについて私が行ってきた方法は次のとおりです。最初の境界セットによって指定されたすべての値を見つけます (例では、(0 1 2))。これは、 と呼ばれる関数によって実行できます(enumerate lowBound highBound)。次に、これらの数値をそれぞれ取得し、次の範囲のセットで各数値をコンスする必要があります。(0 1 2 3)結果は になり((0 0) (0 1) (0 2) (0 3) (1 0)...)ます。

ここまで書いた内容は以下の通りです。

(define (n-loop op . pairs)
     (apply op (generate pairs))
)

(define (generate pairs)
    (map (lambda (x) (cons x (generate (cdr pairs)))) 
         (map (lambda (x) (enumerate (car x) (cadr x))) pairs))
)

しかし、指定された数値については、(0 1 0 1 2 0 1 2 0 1 2)必要なときに出力されます((0 0) (0 1) (0 2) (0 3) (1 0)...)。これは厄介な問題です。誰にも洞察力がありますか?

4

1 に答える 1

1

この問題は、あなたが思っているよりも複雑です。特に、範囲の任意のリストのデカルト積を生成するには、はるかに多くの作業が必要です。3 つ以上の範囲で手順を試しましたか? 興味をそそられたので、今度は完全な解決策を試してみます。解決策として定義された手順のみを使用し、リスト ( 、conscar) 、、および.cdrappendlambdaapplymap

最初に、最も単純なものから最も難しいものまでのヘルパー手順。数値の範囲を生成する方法が必要です。利用可能な場合はbuild-listまたはfor-listを使用しますが、ゼロから実装する必要がある場合は次のようにします。

(define (enumerate low high)
  (if (>= low high)
      '()
      (cons low
            (enumerate (add1 low) high))))

ここで、リスト内の値を折り畳む (削減、累積する) ためのメカニズムが必要です。利用可能な場合は useを使用しfoldr、そうでない場合は次のように実装します。

(define (reduce proc lst init)
  (if (null? lst)
      init
      (proc (car lst)
            (reduce proc (cdr lst) init))))

リストでの不要なネストを避けるには、flatmap値のリストをマップしてフラット化する手順を使用します。

(define (flatmap proc lst)
  (reduce (lambda (e acc)
            (append (proc e) acc))
          lst '()))

これがソリューションの核心です - 範囲を示す値のリストの任意の長いリストのデカルト積を生成する手順です:

(define (product . args)
  (reduce (lambda (pool result)
            (flatmap (lambda (x)
                       (map (lambda (y)
                              (cons x y))
                            result))
                     pool))
          args
          '(())))

最後に、質問の手順。上記で定義されたヘルパー プロシージャを使用します。op受信したパラメータは (指定された範囲の数に応じて) 任意の数を持つことができるため、apply生成された値のタプルごとに使用する必要があります。

(define (n-loop op . pairs)
  (map (lambda (tuple) (apply op tuple))
       (apply product
              (map (lambda (pair)
                     (enumerate (car pair) (cadr pair)))
                   pairs))))

次のようにテストします。

(n-loop (lambda (x y z) (list x y z))
        '(0 2) '(0 3) '(4 6))

> '((0 0 4) (0 0 5) (0 1 4) (0 1 5) (0 2 4) (0 2 5)
    (1 0 4) (1 0 5) (1 1 4) (1 1 5) (1 2 4) (1 2 5))
于 2012-10-22T16:07:28.713 に答える