我正在尝试制作一个只会生成值的序列,直到它找到以下条件并返回列出的结果:
案例头 =
- 0 - 返回 {:origin [除 0 之外的所有生成] :pattern 0}
- 1 - 返回 {:origin nil :pattern [all-generated-values] }
- 重复值 - {:origin [values-before-repeat] :pattern [values-after-repeat]
{
; 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”,因此停止。返回前面作为原点,其余作为模式。
{:origin [9 8] :pattern [4 5 6 7]}
[4 5 6 1] - 找到一个“1”所以停止,所以将所有内容作为模式返回
{:origin nil :pattern [4 5 6 1]}
[3 0 ] - 找到一个 '0' 所以停止
{:origin [3] :pattern [0]}
:else 如果序列达到 x - 1 的长度:
{:origin [all values generated] :pattern nil}
问题
我已经成功地使用 partition-by 在找到重复值的点拆分组,但我想懒惰地这样做。有什么方法可以使用 take-while、condp 或 for 循环的 :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})))
}