我试图创建一个只生成值的序列,直到它找到以下条件并返回列出的结果:
箱头=
{
; 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作为模式返回。
{:origin [9 8] :pattern [4 5 6 7]}4 5 6 1-找到一个'1‘所以停止,所以返回所有的模式
{:origin nil :pattern [4 5 6 1]}3-找到一个'0‘所以停下来
{:origin [3] :pattern [0]}如果序列长度达到x-1,则为:
{:origin [all values generated] :pattern nil}问题
我已经使用了分区,并在找到重复值的地方成功地拆分了组,但我想懒洋洋地这样做。是否可以使用for循环的取时或condp或:while子句来创建条件,以便在找到重复时对其进行分区?
一些尝试
(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进行分区。这有可能吗?就像这样-
{
(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})))}
发布于 2012-10-26 05:06:23
懒散是不可能的:您可以懒洋洋地使用新元素,但您必须保留所有旧元素作为模式使用,因此在(iterate inc 2)这样的序列中,您必须使用所有可用内存。此外,for只允许您同时查看单个元素,因此它不适合此任务。然而,把它写成循环/重述,虽然有点乏味,但并不困难。如果序列在重复、1或0之前结束,您没有指定返回什么,所以我猜到了。
另外,您的第一个示例输出是错误的:它应该停止在1,而不是在4,所以我调整了您的输入。除此之外,这个问题被问得很清楚:谢谢你清楚地说明了问题所在,并描述了你遇到的问题以及你尝试过的问题。
(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]})发布于 2012-10-28 05:55:57
我真正想要做的是找出一个值是否重复并在不使用索引的情况下对seq进行分区。这有可能吗?
我直接实现了您的更新需求。在这种情况下,split-with比partition-by更可取。
;;; 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})))示例:
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]})https://stackoverflow.com/questions/13080697
复制相似问题