2012-08-22 16 views
6

nの0から2^n-1の2進数を生成したいと考えています。例えば、3桁の "000"、 "001"、 "010"、...、 "111"(10進数で0〜7)。私が使用方法はjava.lang.Integer.toBinaryString()メソッドを使用し、必要に応じて、以下のようにゼロを追加することです:クロージャでn桁の2進数を生成する

(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))))) 

このコードでは、私はこのように欲しいものを生成することができます。 3桁の場合:

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

しかし、このコードは少し冗長に見えます。 これを行うには、より良い方法やもっと多くの方法がありますか?

答えて

7

あなたがclojure.pprintからcl-formatを使用して書式設定を簡素化することができます。

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

また(Math/pow 2 n)(bit-shift-left 1 n)と同等であることを知って興味があるかもしれません。これを表現する

もう一つの方法は、clojure.math.combinatoricsからselectionsの期間中に次のようになります。

`CL-format`を使用する理由
(defn binary-permutation [n] 
    (map (partial apply str) (selections [0 1] n))) 
+0

? – noahlz

+1

@noahz cl-formatは、Clojureで利用可能なCommon Lispの出力書式設定関数です(他の言語のprintfに似ています)。 OPがやっていたように、パディングされた2進数を出力するほうが少し簡単です。キーストロークを保存する。あなたには別の選択肢があれば、それを投稿することも自由です。 –

+1

@noahzそして、あなたがなぜこの機能の1つのバージョンを他のものよりも使用するのか尋ねているなら。よく分かりません。私は、範囲ベースのバージョンは少しgrokに簡単だと思います。それはちょうど数えています。しかし、コンビナトリアルソリューションも面白いです。 –

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)))) 
関連する問題