2012-08-22 23 views
6

Me gustaría generar números binarios de n dígitos de 0 a 2^n-1. Por ejemplo, de 3 dígitos, "000", "001", "010", ..., "111" (0 a 7 en decimal). La forma en que utiliza es utilizar java.lang.Integer.toBinaryString() método y añadir ceros si es necesario como la siguiente:Generando números binarios de n dígitos en 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 este código, puedo generar lo que quiero de esta manera. Durante 3 dígitos:

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

pero esto códigos de mirar un poco más detallado. ¿No hay alguna manera mejor o más útil para hacer esto?

Respuesta

7

puede simplificar usando el formato de cl-formatclojure.pprint:

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

Usted también podría estar interesado en saber que (Math/pow 2 n) es equivalente a (bit-shift-left 1 n).

Otra forma de expresar esto sería en términos de selections de clojure.math.combinatorics:

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

Por qué usar 'cl-format'? – noahlz

+1

@noahz cl-format es una función de formato de salida de Common Lisp que está disponible en Clojure (similar a printf en otros idiomas). Simplemente facilita un poco los números binarios acolchados como lo hacía el OP. Guardando las teclas. Si tiene una alternativa, no dude en publicarla también. –

+1

@noahz Y si está preguntando por qué usa una versión de esta función sobre la otra. No estoy seguro. Yo diría que la versión basada en rango es un poco más simple de asimilar. Solo está contando. Pero la solución combinatoria también es interesante. –

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)))) 
Cuestiones relacionadas