2012-08-22 8 views
6

Ich möchte Binärzahlen von n Ziffern von 0 bis 2^n-1 generieren. Zum Beispiel aus 3 Ziffern, "000", "001", "010", ..., "111" (0 bis 7 in Dezimal). Die Art, wie ich verwendete java.lang.Integer.toBinaryString() Methode zu verwenden, und fügen Nullen bei Bedarf wie folgt aus:Erzeugen von Binärzahlen von n Ziffern in clojure

(defn pad-zero [s n] 
    (str (reduce str (repeat (- n (count s)) "0")) s)) 

(defn binary-permutation [n] 
    (map (fn [s] (pad-zero s n)) 
     (map #(Integer/toBinaryString %) (range 0 (Math/pow 2 n))))) 

Mit diesem Code kann ich generieren, was ich so wollen. Für 3 Ziffern:

(binary-permutation 3) 
=> ("000" "001" "010" "011" "100" "101" "110" "111") 

Aber diese Codes sehen ein wenig aus. Gibt es keinen besseren oder besseren Weg, dies zu tun?

Antwort

7

Sie können die Formatierung vereinfachen mit cl-format von clojure.pprint:

(defn binary-permutation [n] 
    (map (partial cl-format nil "~v,'0B" n) (range 0 (Math/pow 2 n)))) 

Sie könnten auch interessiert sein zu wissen, dass (Math/pow 2 n)-(bit-shift-left 1 n) entspricht.

andere Möglichkeit, dies auszudrücken in der Bezeichnung der selections von clojure.math.combinatorics wäre:

(defn binary-permutation [n] 
    (map (partial apply str) (selections [0 1] n))) 
+0

Warum 'cl-format'? – noahlz

+1

@noahz cl-format ist eine Ausgabeformatierungsfunktion von Common Lisp, die in Clojure verfügbar ist (ähnlich wie printf in anderen Sprachen). Es macht es nur ein bisschen einfacher, gepolsterte Binärzahlen auszugeben, wie es das OP tat. Speichern einer Tastenkombination. Wenn Sie eine Alternative haben, zögern Sie nicht, es auch zu posten. –

+1

@noahz Und wenn Sie fragen, warum verwenden Sie eine Version dieser Funktion über die andere. Ich bin mir nicht sicher. Ich würde sagen, dass die range-basierte Version ein wenig einfacher zu grok ist. Es zählt nur. Aber auch die Kombinatorik ist interessant. –

2
(defn binary-permutation [n] 
    (for [x (range (Math/pow 2 n))] 
    (apply str (reverse (take n (map #(bit-and 1 %) (iterate #(bit-shift-right % 1) x))))))) 

(defn pad-zero [s n] 
    (apply str (take-last n (concat (repeat n \0) s))))