Манипуляция со списком закрытия - PullRequest
4 голосов
/ 26 января 2012

Я хочу взять список и сгенерировать подпоследовательности следующим образом:

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

и да, порядок имеет значение. Я могу упустить что-то очевидное, но я застрял. Бонусные баллы за красивые решения!

Ответы [ 6 ]

4 голосов
/ 26 января 2012

Еще один дубль, немного короче.

(defn subs4 [coll]
   (mapcat #(reverse (take (count %) (iterate butlast %)))
      (take (count coll) (iterate rest coll))))
4 голосов
/ 26 января 2012
(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 - безопасный вариант ответа Понзао.

Редактировать: Еще одно использование 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 только один раз при запуске.

(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))))
3 голосов
/ 26 января 2012
(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))))
3 голосов
/ 26 января 2012

Моя версия с рекурсией:

(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))
3 голосов
/ 26 января 2012
(defn subseqs
  [[x & xs :as coll]]
  (when (seq coll)
    (lazy-cat
     (for [n (range 1 (inc (count coll)))]
       (take n coll))
     (subseqs xs))))
2 голосов
/ 26 января 2012

Нет необходимости в рекурсии, просто вложенный в петлю простой элемент

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

и еще один

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

Только что заметил, что это примерно то же самое, что и версия e-i-s. Я пытался свернуть мою собственную версию butlast (из-за симметрии с «iterate next»), но никто не делал вещи более краткими, чем вложенные циклы for. До тех пор, пока я не нашел butlast на clojuredocs.

В любом случае, попробуйте проблемы 4clojure. Неспособность найти ответы действительно заставляет вас найти ответ, любой ответ, который работает, и если вы делаете / сделали, вы найдете более элегантный ответ. И если у вас нет идеи, обычно есть ответы других пользователей, которые просвещают или вдохновляют после того, как вы это решили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...