首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在重复处停止和拆分生成的序列- clojure

在重复处停止和拆分生成的序列- clojure
EN

Stack Overflow用户
提问于 2012-10-26 04:23:03
回答 2查看 363关注 0票数 4

我试图创建一个只生成值的序列,直到它找到以下条件并返回列出的结果:

箱头=

  • 0-返回{:原产地除0:模式0}外所有生成的
  • 1-返回{:origin :模式所有生成的值}
  • 重复-值-{:源值-前-重复:模式值-后-重复

{

代码语言:javascript
复制
; n = int
; x = int
; hist - all generated values

; Keeps the head below x 
(defn trim-head [head x]
  (loop [head head]
    (if (> head x)
      (recur (- head x))
      head)))

; Generates the next head
(defn next-head [head x n]
  (trim-head (* head n) x))

(defn row [x n]
   (iterate #(next-head % x n) n))

; Generates a whole row - 
; Rows are a max of x - 1.
(take (- x 1) (row 11 3))

在到达行尾之前要停止的案例示例:

9,8,4,5,6,7,4- '4‘被重复,所以停止。以原点返回,rest作为模式返回。

代码语言:javascript
复制
{:origin [9 8] :pattern [4 5 6 7]}

4 5 6 1-找到一个'1‘所以停止,所以返回所有的模式

代码语言:javascript
复制
{:origin nil :pattern [4 5 6 1]}

3-找到一个'0‘所以停下来

代码语言:javascript
复制
{:origin [3] :pattern [0]}

如果序列长度达到x-1,则为:

代码语言:javascript
复制
{:origin [all values generated] :pattern nil}

问题

我已经使用了分区,并在找到重复值的地方成功地拆分了组,但我想懒洋洋地这样做。是否可以使用for循环的取时或condp或:while子句来创建条件,以便在找到重复时对其进行分区?

一些尝试

代码语言:javascript
复制
(take 2 (partition-by #(= 1 %) (row 11 4)))

(for [p (partition-by #(stop-match? %) head) (iterate #(next-head % x n) n)
        :while (or (not= (last p) (or 1 0 n) (nil? (rest p))]
  {:origin (first p) :pattern (concat (second p) (last p))}))

#更新

我真正想要做的是找出一个值是否重复并在不使用索引的情况下对seq进行分区。这有可能吗?就像这样-

{

代码语言:javascript
复制
(defn row [x n]
  (loop [hist [n]
         head (gen-next-head (first hist) x n)
         steps 1]
    (if (>= (- x 1) steps)
      (case head
        0 {:origin [hist] :pattern [0]}
        1 {:origin nil :pattern (conj hist head)}
        ; Speculative from here on out 
        (let [p (partition-by #(apply distinct? %) (conj hist head))]
          (if-not (nil? (next p)) ; One partition if no repeats.
            {:origin (first p) :pattern (concat (second p) (nth 3 p))}
            (recur (conj hist head) (gen-next-head head x n) (inc steps)))))
      {:origin hist :pattern nil})))

}

EN

回答 2

Stack Overflow用户

发布于 2012-10-26 05:06:23

懒散是不可能的:您可以懒洋洋地使用新元素,但您必须保留所有旧元素作为模式使用,因此在(iterate inc 2)这样的序列中,您必须使用所有可用内存。此外,for只允许您同时查看单个元素,因此它不适合此任务。然而,把它写成循环/重述,虽然有点乏味,但并不困难。如果序列在重复、1或0之前结束,您没有指定返回什么,所以我猜到了。

另外,您的第一个示例输出是错误的:它应该停止在1,而不是在4,所以我调整了您的输入。除此之外,这个问题被问得很清楚:谢谢你清楚地说明了问题所在,并描述了你遇到的问题以及你尝试过的问题。

代码语言:javascript
复制
(defn trim-head [coll]                                                      
  (loop [so-far [], indexes {}, index 0, coll (seq coll)]                   
    (if-not coll                                                            
      {:origin nil, :pattern so-far} ;; ?? not specified in question        
      (let [x (first coll), xs (rest coll)]                                 
        (if (contains? indexes x)                                           
          {:origin (subvec so-far 0 (indexes x))                            
           :pattern (subvec so-far (indexes x))}                            
          (case x                                                           
            0 {:origin so-far, :pattern [x]}                                
            1 {:origin nil, :pattern (conj so-far x)}                       
            (recur (conj so-far x) (assoc indexes x index) (inc index) (seq xs))))))))

user> (map trim-head [[9 8 2 4 5 6 7 4] [4 5 6 1] [3 0]])                       
({:origin [9 8 2], :pattern [4 5 6 7]}
 {:origin nil, :pattern [4 5 6 1]} 
 {:origin [3], :pattern [0]})
票数 1
EN

Stack Overflow用户

发布于 2012-10-28 05:55:57

我真正想要做的是找出一个值是否重复并在不使用索引的情况下对seq进行分区。这有可能吗?

我直接实现了您的更新需求。在这种情况下,split-withpartition-by更可取。

代码语言:javascript
复制
;;; find out if a value has repeated, but considering zero and one.
(defn- generate
  "Returns a vector of [duplicate-value values-until-duplicate].
   duplicate-value might be zero or one."
  [s]
  (->> [s [] #{0 1}]
       (iterate (fn [[[head & more] generated idx]]
                  [more (conj generated head) (conj idx head)]))
       (take-while (comp seq first))
       (drop-while (fn [[[head & _] _ idx]]
                     (nil? (idx head))))
       first
       ((juxt ffirst second))))

;;; partition the seq without using the index.
(defn partition-by-duplicate
  [s]
  (let [[pivot generated-values] (generate s)]
    (cond (= 0 pivot) {:origin generated-values, :pattern [0]}
          (= 1 pivot) {:origin nil, :pattern (conj generated-values 1)}
          pivot (->> generated-values
                     (split-with (partial not= pivot))
                     (interleave [:pattern :origin])
                     (apply hash-map))
          :else {:origin s, :pattern nil})))

示例:

代码语言:javascript
复制
user> (map generate [[9 8 2 4 5 6 7 4] [4 5 6 1] [3 0]])
([4 [9 8 2 4 5 6 7]]
 [1 [4 5 6]]
 [0 [3]])

user> (map partition-by-duplicate [[9 8 2 4 5 6 7 4] [4 5 6 1] [3 0]])
({:pattern (9 8 2), :origin (4 5 6 7)}
 {:origin nil, :pattern [4 5 6 1]}
 {:origin [3], :pattern [0]})
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13080697

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档