Ich versuche eine Methode zu implementieren, die eine Liste von Listen nimmt und das kartesische Produkt dieser Listen zurückgibt.Kartesisches Produkt in clojure
Hier ist, was ich bisher:
(defn cart
([] '())
([l1] (map list l1))
([l1 l2]
(map
(fn f[x] (map
(fn g [y] (list x y))
l2))
l1)
)
)
(defn cartesian-product [& lists]
(reduce cart lists)
)
;test cases
(println (cartesian-product '(a b) '(c d))) ; ((a c) (a d) (b c) (b d))
(println (cartesian-product())) ;()
(println (cartesian-product '(0 1))) ; ((0) (1))
(println (cartesian-product '(0 1) '(0 1))) ; ((0 0) (0 1) (1 0) (1 1))
(println (apply cartesian-product (take 4 (repeat (range 2))))) ;((0 0 0 0) (0 0 0 1) (0 0 1 0) (0 0 1 1) (0 1 0 0) (0 1 0 1) (0 1 1 0) (0 1 1 1) (1 0 0 0) (1 0 0 1) (1 0 1 0) (1 0 1 1) (1 1 0 0) (1 1 0 1) (1 1 1 0) (1 1 1 1))
Das Problem ist meine Lösung wirklich ist 'brackety'.
(((a c) (a d)) ((b c) (b d)))
()
(0 1)
(((0 0) (0 1)) ((1 0) (1 1)))
(((((((0 0) (0 1)) 0) (((0 0) (0 1)) 1)) 0) (((((0 0) (0 1)) 0) (((0 0) (0 1)) 1)) 1)) ((((((1 0) (1 1)) 0) (((1 0) (1 1)) 1)) 0) (((((1 0) (1 1)) 0) (((1 0) (1 1)) 1)) 1)))
Ich versuchte
(apply concat(reduce cart lists))
Zugabe, aber dann bekomme ich einen Absturz wie so:
((a c) (a d) (b c) (b d))
()
IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:494)
Also, ich glaube, ich bin in der Nähe, aber etwas fehlt. Aber da ich so neu in clojure und funktionaler Programmierung bin, könnte ich auf dem völlig falschen Weg sein. Bitte helfen Sie! :)
Es gibt ein schnelles kartesisches Produkt in clojure.math.combinatorics (https://github.com/clojure/math.combinatorics/), das nützlich ist, wenn Sie nur das Ergebnis wollen ... –
Prost, es ist mehr eine Übung obwohl :) –