在Clojure中创建所有值的序列

时间:2018-11-26 08:10:46

标签: clojure

我目前正在处理kata代码挑战,它具有一些要求:

  1. u(0)= 1是u中的第一个数字。
  2. 对于u中的每个x,也必须在u中也包含y = 2 * x + 1和z = 3 * x + 1。
  3. 你没有其他数字。

我构造了一些功能:

(defn test2 [x n orgN] ;;x is a counter, n is what I want returned as a list
  (println n)
  (println "this is x: " x)
  (cons n (if (not= x (- orgN 1 )) 
   (do (test2 (+ x 1) (+ 1 (* n 2)) orgN)
   (test2  (+ x 1) (+ 1 (* n 3)) orgN))
  nil)
))

(defn test2helper [n]
  (def x 1)
  (test2 x x n) 
)


(test2helper 5)

但是,这仅返回(1 4 13 40),并且错过了之间的一整堆值。 Cons只根据最近的3n + 1算法构造一个列表,而当我想要从重复的每个n值生成的两个值的序列时,不选择任何其他值。我的问题是,有没有一种方法可以构造所有值的序列,而不是仅构造其中的4个?

https://www.codewars.com/kata/twice-linear/train/clojure

2 个答案:

答案 0 :(得分:1)

此解决方案几乎是正确的。但是请记住,do用于产生副作用,而不是用于产生值。具体来说,(do x y)y中产生副作用后返回x。但是test2没有任何副作用:它只返回一个列表。您正在寻找的是(concat x y),该函数将两个列表连接在一起成为一个更大的列表。

答案 1 :(得分:0)

尽管Alan Malloy's solution回答了您的问题,但它不能解决the problem you refer to,这需要按递增顺序生成序列。

我的方法是按照以下模式延迟生成序列:

(defn recurrence [f inits]
  (map first (iterate f inits)))

例如,您可以这样定义斐波那契数列:

(defn fibonacci []
  (recurrence (fn [[a b]] [b (+ a b)]) [1 1]))

=> (take 10 (fibonacci))
(1 1 2 3 5 8 13 21 34 55)

难以生成所需的序列。好打猎!