小编Thu*_*ail的帖子

Clojure中快速素数生成

我一直在努力解决Clojure中的Project Euler问题,以便变得更好,而且我已经遇到了几次素数.我的问题是它只是花了太长时间.我希望有人可以帮我找到一种以Clojure-y方式做到这一点的有效方法.

当我拳头做到这一点时,我粗暴地强迫它.这很容易做到.但是计算10001个素数在Xeon 2.33GHz上用了2分钟,对规则来说太长了,一般来说太长了.这是算法:

(defn next-prime-slow
    "Find the next prime number, checking against our already existing list"
    ([sofar guess]
        (if (not-any? #(zero? (mod guess %)) sofar)
            guess                         ; Then we have a prime
            (recur sofar (+ guess 2)))))  ; Try again                               

(defn find-primes-slow
    "Finds prime numbers, slowly"
    ([]
        (find-primes-slow 10001 [2 3]))   ; How many we need, initial prime seeds
    ([needed sofar]
        (if (<= needed (count sofar))
            sofar                         ; Found enough, we're done
            (recur needed (concat sofar [(next-prime-slow …
Run Code Online (Sandbox Code Playgroud)

lisp primes clojure

47
推荐指数
5
解决办法
1万
查看次数

如何在Clojure中实现延迟序列?

我喜欢Clojure.困扰我的一个问题是我不知道如何实现懒惰的序列,或者它们是如何工作的.

我知道懒惰序列只评估序列中要求的项目.它是如何做到的?

  • 什么使得延迟序列如此高效以至于它们不会消耗太多堆栈?
  • 为什么你可以在延迟序列中包装递归调用,并且不再为大型计算获得堆栈溢出?
  • 懒惰序列消耗什么资源来做它做的事情?
  • 在什么情况下懒惰序列效率低下?
  • 在什么情况下懒惰序列最有效?

lisp clojure lazy-evaluation lazy-sequences

29
推荐指数
3
解决办法
3588
查看次数

习惯性/高效的Clojure方式交叉两个先验分类的向量?

我有一对向量xy独特的项目,我知道每个项目都要排序.我希望有两者的交集,维持排序顺序.理想情况下,结果将是另一个向量,用于快速随机访问.

下面的代数仅仅是为了举例,我xy将会预先分类和预先分开(它们实际上是时间样本).

(defn gen-example [c] (-> (repeatedly c #(-> c rand int)) distinct sort vec))

user=> (def x (gen-example 100000)) (count x)
#'user/x
63161
user=> (def y (gen-example 100000)) (count y)
#'user/y
63224
Run Code Online (Sandbox Code Playgroud)

我知道Clojure clojure.set/intersection可以用于sorted-set.我xy具有相同的属性(排序不同的元素)但不是相同的类型.

问题1:是否有转换更好/更快的方式x,并ysorted-set除S (apply sorted-set x)因为他们已经明显和排序?

user=> (time (def ssx (apply sorted-set x)))
"Elapsed time: 607.642592 msecs"
user=> (time (def ssy (apply sorted-set y)))
"Elapsed …
Run Code Online (Sandbox Code Playgroud)

vector clojure

10
推荐指数
1
解决办法
1443
查看次数

过滤Clojure中的字母字符

我想过滤掉集合中的字母字符.例如,我只想要A B c d来自的角色"A(B%$c32d".是使用正则表达式的唯一方法吗?

clojure

8
推荐指数
3
解决办法
3155
查看次数

如何理解clojure的懒惰seq

我试图理解clojure的lazy-seq运算符,以及懒惰评估的概念.我知道这个概念背后的基本思想:表达式的评估会延迟到需要的值.

一般来说,这可以通过两种方式实现:

  • 在编译时使用宏或特殊形式;
  • 在运行时使用lambda函数

使用惰性求值技术,可以构造被评估为已消耗的无限数据结构.这些无限序列利用lambdas,闭包和递归.在clojure中,这些无限数据结构是使用lazy-seqcons形成的.

我想知道lazy-seq它是如何神奇的.我知道它实际上是一个宏.请考虑以下示例.

(defn rep [n]
  (lazy-seq (cons n (rep n))))
Run Code Online (Sandbox Code Playgroud)

这里,rep函数返回一个延迟评估的类型序列LazySeq,现在可以使用序列API对其进行转换和使用(从而进行求值).这个API提供的功能take,map,filterreduce.

在扩展形式中,我们可以看到lambda如何用于存储单元格的配方而不立即进行评估.

(defn rep [n]
  (new clojure.lang.LazySeq (fn* [] (cons n (rep n))))) 
Run Code Online (Sandbox Code Playgroud)
  • 序列API实际上如何使用LazySeq
  • 以下表达式实际发生了什么

(reduce + (take 3 (map inc (rep 5))))

  • 如何将中间操作map应用于序列,
  • 如何take限制序列
  • 终端操作如何reduce评估序列

另外,这些功能如何与a Vector或a一起使用LazySeq

此外, …

lisp recursion lambda clojure lazy-evaluation

8
推荐指数
1
解决办法
1125
查看次数

协议中的提示返回类型是否在Clojure中有任何影响?

您可以在协议中提示返回类型

(defprotocol Individual
  (^Integer age [this]))
Run Code Online (Sandbox Code Playgroud)

并且编译器将使您的方法符合:

(defrecord person []
  Individual
  (^String age [this] "one"))

; CompilerException java.lang.IllegalArgumentException: Mismatched return type: age, expected: java.lang.Object, had: java.lang.String, ...
Run Code Online (Sandbox Code Playgroud)

但是您不必遵守类型提示:

(defrecord person []
  Individual
  (age [this] "one"))

(age (new person))
; "one"
Run Code Online (Sandbox Code Playgroud)

类型提示有效吗?


这是一个跟进可以在clojure defrecord中指定方法的返回类型吗?

clojure

7
推荐指数
1
解决办法
800
查看次数

如何使Clojure在编译时评估常量局部表达式

追求4Clojure 问题178 - 最好的手,我有这个用于将卡值从字符转换为数字:

 (fn [ch]
   (or
    ({\A 1} ch)
    ((zipmap "TJQK" (iterate inc 10)) ch)
    (- (int ch) (int \0))))
Run Code Online (Sandbox Code Playgroud)

zipmap每次通话表达式,总是产生{\K 13, \Q 12, \J 11, \T 10}.

我们怎样才能让编译器只评估一次?


经过多次脑力激荡,我想到了

(defmacro constant [exp] (eval exp))
Run Code Online (Sandbox Code Playgroud)

...包裹zipmap呼叫:

(constant (zipmap "TJQK" (iterate inc 10)))
Run Code Online (Sandbox Code Playgroud)

我认为这相当于

(eval '(zipmap "TJQK" (iterate inc 10)))
Run Code Online (Sandbox Code Playgroud)

......但不是eval没有引用:

(eval (zipmap "TJQK" (iterate inc 10)))
Run Code Online (Sandbox Code Playgroud)

欢迎更正,评论和改进.

clojure

6
推荐指数
1
解决办法
561
查看次数

Clojure:O(1) 函数检查序列是否恰好有 1 个元素

Clojure 中是否有一种快速方法来检查序列是否恰好有 1 个元素?请注意,序列可能包含 nils。

如果我正确读取源代码,调用count序列需要 O(n) 时间。

替代解决方案:

(and
  (not (empty? a-seq))
  (empty? (rest a-seq)))
Run Code Online (Sandbox Code Playgroud)

文档说调用empty?集合与coll调用相同(not (seq coll)),但他们没有指定其效率或调用empty?序列时会发生什么。我尝试在 github 存储库中搜索其empty?实现方式,但它忽略了搜索中的问号,并且出现了大量“空”的点击。我想empty?restO(1),但话又说回来,count不是......

performance functional-programming predicate clojure

5
推荐指数
1
解决办法
1009
查看次数

为什么需要使用以防止无限递归

在定义无限序列时,我注意到缺点是避免无限递归.但是,我不明白的是为什么.这是有问题的代码:

(defn even-numbers
  ([] (even-numbers 0))
  ([n] (cons n (lazy-seq (even-numbers (+ 2 n))))))

(take 10 (even-numbers))
;; (0 2 4 6 8 10 12 14 16 18)
Run Code Online (Sandbox Code Playgroud)

这很好用; 但由于我喜欢质疑,我开始想知道为什么需要利弊(除了包括0).毕竟,lazy-seq函数创建了一个lazy-seq.这意味着,在调用(或分块)之前,不应计算其余值.所以,我试过了.

(defn even-numbers-v2
  ([] (even-numbers-v2 0))
  ([n] (lazy-seq (even-numbers-v2 (+ 2 n)))))

(take 10 (even-numbers-v2))
;; Infinite loooooooooop
Run Code Online (Sandbox Code Playgroud)

所以,现在我知道缺点是必要的,但是我想知道为什么有必要对所谓的懒惰序列进行惰性评估

clojure lazy-evaluation

4
推荐指数
1
解决办法
132
查看次数

将defmulti转换为defprotocol

是否可以转换以下代码,使其使用defprotocoldefrecord代替defmultiand defmethod

(defmulti test-multimethod (fn [keyword] keyword))

(defmethod test-multimethod :foo [a-map]
  "foo-method was called")

(defmethod test-multimethod :bar [a-map]
  "bar-method was called")

(defmulti perimeter (fn [shape] (:shape-name shape)))
(defmethod perimeter :circle [circle]
  (* 2 Math/PI (:radius circle)))
(defmethod perimeter :rectangle [rectangle]
  (+ (* 2 (:width rectangle)) (* 2 (:height rectangle))))

(def some-shapes [{:shape-name :circle :radius 4}
                   {:shape-name :rectangle :width 2 :height 2}])

(defmulti area (fn [shape] (:shape-name shape)))
(defmethod area :circle [circle]
  (* Math/PI …
Run Code Online (Sandbox Code Playgroud)

clojure

3
推荐指数
1
解决办法
119
查看次数