2012-08-22 16 views
6

Mi piacerebbe generare numeri binari di n cifre da 0 a 2^n-1. Ad esempio di 3 cifre, "000", "001", "010", ..., "111" (da 0 a 7 in decimale). Il modo che ho usato è quello di utilizzare il metodo java.lang.Integer.toBinaryString() e aggiungere zeri, se necessario, come la seguente:Generazione di numeri binari di n cifre nel 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))))) 

Con questo codice, è possibile generare quello che voglio come questo. Per 3 cifre:

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

Ma questo codice sembra un po 'prolisso. Non ci sono modi migliori o più corti per farlo?

risposta

7

È possibile semplificare la formattazione utilizzando cl-format da clojure.pprint:

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

Si può anche essere interessati a sapere che (Math/pow 2 n) è equivalente a (bit-shift-left 1 n).

Un altro modo per esprimere questo sarebbe in termini di selections da clojure.math.combinatorics:

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

Perché usare 'cl-format'? – noahlz

+1

@noahz cl-format è una funzione di formattazione dell'output di Common Lisp disponibile in Clojure (simile a printf in altre lingue). Semplicemente rende un po 'più facile l'output di numeri binari riempiti come stava facendo l'OP. Salvataggio di una sequenza di tasti. Se hai un'alternativa, sentiti libero di postarlo pure. –

+1

@noahz E se ti stai chiedendo perché usare una versione di questa funzione rispetto all'altra. Non ne sono sicuro. Direi che la versione basata sull'intervallo è un po 'più semplice da usare. Sta solo contando. Ma anche la soluzione combinatoria è interessante. –

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)))) 
Problemi correlati