まず、cartesian-product
の機能があればcartesian-product
をracket/list
から使用できます。
> (cartesian-product
(list '(10 11) '(20 21))
(list '('u 'v) '('p 'q)))
'(((10 11) ('u 'v)) ((10 11) ('p 'q)) ((20 21) ('u 'v)) ((20 21) ('p 'q)))
テストケースが内部リストをスプライスするため、テストケースがこれとは多少異なります。これはそうではありません。しかし、それが必要ならば簡単に(map append* ...)
で修正できます。 append*
関数は、1レベル下のリストのリストを平坦化します。
> (define (mix-rows rows1 rows2)
(map append* (cartesian-product rows1 rows2)))
> (mix-rows
(list '(10 11) '(20 21))
(list '('u 'v) '('p 'q)))
'((10 11 'u 'v) (10 11 'p 'q) (20 21 'u 'v) (20 21 'p 'q))
あなたが最初からそれを設計したい場合は、あなたの実装に問題がfoldr
が機能(X Y -> Y)
、2つの引数の機能を期待していることですが、あなたはそれを機能(Row -> Row)
、1つの引数関数を与えたが。あなたはそれを修正することができますが、私が見ることのできるところから、実際にはfoldr
は必要ありません。おそらくmap
も意味していました。
(define mix-rows
(lambda (rows1 rows2)
(map (lambda (row1)
(map (lambda (row2)
(append row1 row2))
rows2))
rows1)))
、これはまだネストされたリストの余分な層を取り除くために
> (mix-rows
(list '(10 11) '(20 21))
(list '('u 'v) '('p 'q)))
'(((10 11 'u 'v) (10 11 'p 'q)) ((20 21 'u 'v) (20 21 'p 'q)))
を生成、テストケースを失敗していますが、リストの1レベル下のリストを平らにするappend*
を使用することができます。
;; Signature: mix-rows(rows1 rows2)
;; Purpose: returns a list of rows of the cartesian product of both rows
;; Type: [ List(Row) * List(Row) -> List(Row) ]
;; Tests:
;; (mix-rows (list '(10 11) '(20 21)) (list '('u 'v) '('p 'q)))
;; ==> ((10 11 'u 'v)
;; (10 11 'p 'q)
;; (20 21 'u 'v)
;; (20 21 'p 'q))
(define mix-rows
(lambda (rows1 rows2)
(append*
(map (lambda (row1)
(map (lambda (row2)
(append row1 row2))
rows2))
rows1))))
しかし、あなたは本当のデカルト積をしたい場合は、行をスプライシングすることなく、あなたは(list row1 row2)
に(append row1 row2)
を変更することにより、それを修正することができます。
(define mix-rows
(lambda (rows1 rows2)
(append*
(map (lambda (row1)
(map (lambda (row2)
(list row1 row2))
rows2))
rows1))))
次に、cartesian-product
と一致します。
あなたは 'uvpq'を二重引用するつもりはないでしょう。'(list(quote u)(quote v)) 'のsugaredバージョンである' '(uv)と ''(pq) '(list(quote p)(quote q))' – naomik