在 clojure 中使用范围的惰性序列生成器
Lazy-seq generator using range in clojure
说我想创建一个从 1 到 m
的所有数字的惰性序列,它们与 m
的最大公约数等于 1
:
(def m 38941629971148227236N)
(def possible-e
(lazy-seq (filter #(= 1 (gcd % m)) (range 1 m) ))
)
然后我可以take
一个像
这样的序列
(take 10 possible-e)
=> (1 3 5 7 9 11 13 15 17 19)
但是当我尝试以不同的方式做同样的事情时,事情就不起作用了。我认为它正在计算所有数字,因为打印任何东西都需要很长时间:
(def possible-e
(lazy-seq (filter #(= 1 (gcd % m)) (reverse (range 1 m)) ))
)
为什么它的工作方式不同?有什么解决办法?
问题出在这里:
(reverse (range 1 m))
在您的代码可以移动到 filter
之前,它必须计算完整 range
。您可以将 range
与负步一起使用:
(def possible-e
(lazy-seq (filter #(= 1 (gcd % m)) (range (dec m) 0 -1)))
)
扩展评论:
filter
是懒惰的,所以 lazy-seq
在这两种情况下都是多余的。
- 不要
(def m ...)
。将 possible-e
设为参数为 m
的函数。
所以我们得到
(defn possible-e [m]
(filter #(= 1 (gcd % m)) (range 1 m)))
(def m 38941629971148227236N)
和
(defn possible-e [m]
(filter #(= 1 (gcd % m)) (reverse (range 1 m))))
说我想创建一个从 1 到 m
的所有数字的惰性序列,它们与 m
的最大公约数等于 1
:
(def m 38941629971148227236N)
(def possible-e
(lazy-seq (filter #(= 1 (gcd % m)) (range 1 m) ))
)
然后我可以take
一个像
(take 10 possible-e)
=> (1 3 5 7 9 11 13 15 17 19)
但是当我尝试以不同的方式做同样的事情时,事情就不起作用了。我认为它正在计算所有数字,因为打印任何东西都需要很长时间:
(def possible-e
(lazy-seq (filter #(= 1 (gcd % m)) (reverse (range 1 m)) ))
)
为什么它的工作方式不同?有什么解决办法?
问题出在这里:
(reverse (range 1 m))
在您的代码可以移动到 filter
之前,它必须计算完整 range
。您可以将 range
与负步一起使用:
(def possible-e
(lazy-seq (filter #(= 1 (gcd % m)) (range (dec m) 0 -1)))
)
扩展评论:
filter
是懒惰的,所以lazy-seq
在这两种情况下都是多余的。- 不要
(def m ...)
。将possible-e
设为参数为m
的函数。
所以我们得到
(defn possible-e [m]
(filter #(= 1 (gcd % m)) (range 1 m)))
(def m 38941629971148227236N)
和
(defn possible-e [m]
(filter #(= 1 (gcd % m)) (reverse (range 1 m))))