2012-01-26 36 views
4

私は、このように、リストを取り、サブ配列を生成する:Clojureのリスト操作

(subs '(1 2 3)) 
; should evaluate to ((1) (1 2) (1 2 3) (2) (2 3) (3)) 

とはい、順序が重要。私は明らかに何かを見逃しているかもしれないが、私は立ち往生している。かなりのソリューションのためのボーナスポイント!ループ

(defn subs 
    [seq] 
    (let [c (count seq)] 
     (remove empty? 
     (for [x (range c) y (range (- (inc c) x))] 
      (take y (drop x seq)))))) 

と別の1

(defn subs 
    [seq] 
(letfn [(take-len [f s] (take (count s) (iterate f s)))] 
    (mapcat #(reverse (take-len butlast %)) (take-len next seq)))) 

ためのネストされた単なるオーレ

+1

再帰的に考える。 '(2 3)'のすべての部分列を生成できれば、 '(1 2 3)'のすべての部分列を得ることができますか? – Peteris

答えて

4

別テイク、少し短いです。

(defn subs4 [coll] 
    (mapcat #(reverse (take (count %) (iterate butlast %))) 
     (take (count coll) (iterate rest coll)))) 
2

必要ありません再帰が、ただ、これはのE-あるバージョンとほぼ同じである気づきました。自分のバージョンのbutlastをロールバックしようとしていましたが(これは、 "next iterate"という対称性のためです)、ネストされたforループよりも簡潔にするものはありませんでした。私がクローズド・ドックを知るまでは。

とにかく、4clojureの問題を試してみてください。答えに到達することができないということは、本当にあなたが答えを見つけ出すこと、それが働く答え、そしてあなたがやっている/行ったことがあれば、よりエレガントなものを見つけることになります。あなたが気づかない場合は、通常、解決した後に啓発したりインスピレーションを与える他のユーザーの回答があります。再帰と

+0

私は本当にクールな[Clojure cheatseet](http://clojure.org/cheatsheet)で 'butlast'を見つけました。 – MisterMetaphor

3
(defn subseqs 
    [[x & xs :as coll]] 
    (when (seq coll) 
    (lazy-cat 
    (for [n (range 1 (inc (count coll)))] 
     (take n coll)) 
    (subseqs xs)))) 
3

マイバージョン:ponzaoの答えに

(defn my-subs 
    ([lst] (my-subs lst (count lst))) 
    ([lst, len] 
    (when (> len 0) 
     (concat 
     (for [i (range 1 (+ 1 len))] 
      (take i lst)) 
     (my-subs (rest lst) (- len 1)))))) 

(my-subs '(1 2 3))       
; => ((1) (1 2) (1 2 3) (2) (2 3) (3)) 
4
(defn subseqs 
    [coll] 
    (lazy-seq 
    (when-let [s (seq coll)] 
     (let [n (inc (count coll))] 
     (concat (map take (range 1 n) (repeat s)) 
       (subseqs (rest s))))))) 

nil -safeバリエーション。

編集:もう1つはreductionsです。

(defn subseqs 
    [coll] 
    (lazy-seq 
    (when-let [s (seq coll)] 
     (let [fst (first s) 
      rst (rest s)] 
     (concat (reductions conj [fst] rst) (subseqs rst)))))) 

注意:このバージョンは完全に怠惰です。あなたが最初の完全なサブシーケンスをたどるまで、まあ。これはあなたが得るほど怠惰です。

次のバージョンも完全に怠惰ですが、起動時にreductionsを1回だけ構築します。

(defn subseqs 
    [coll] 
    (let [step (fn step [subcolls] 
       (lazy-seq 
       (when-let [s (next subcolls)] 
        (concat s (step (map next s))))))] 
    (step (reductions conj [] coll)))) 
+0

良いキャッチ、私は私の答えでこれを修正します。 – ponzao

3
(defn subs3 [coll] 
    (apply concat 
    [] 
    (map 
     #(reverse (for [x (iterate butlast %) :while (not-empty x)] x)) 
     (for [x (iterate rest coll) :while (not-empty x)] x))))