Clojure 正则表达式也能这么用

wushexu · 2015年07月05日 · 最后由 wushexu 回复于 2015年07月12日 · 7384 次阅读

4clojure 的一道题(http://www.4clojure.com/problem/67),找素数:

(= (__ 2) [2 3])
(= (__ 5) [2 3 5 7 11])
(= (last (__ 100)) 541)

下划线部分是要填的一个函数,要返回前 n 个素数。输入参数 2,返回 [2 3];输入 5,返回 [2 3 5 7 11]。

发现有这么一个 solution,

(fn [n]
  (take
    n
    (filter
      #(empty? (re-matches #"^(11+?)\1+$" (apply str (repeat % "1"))))
      (drop 2 (range)))))

很有创意,不是吗?正则表达式也能这么用^_^(效率另说)。

=====================================================

BTW,不考虑效率,这个是比较短的:

(fn [n] 
  (->>
  (range)
  (drop 2)
  (filter (fn [x] (every? #(< 0 (mod x %)) (range 2 x))))
  (take n)))

我自己提交的是这样的(考虑了效率):

(fn [i]
    (loop [i i n 3 ps [2]]
        (if (= i 1)
            ps
            (let [upper (inc (int (Math/sqrt n)))
                  ps2 (filter #(< % upper) ps)
                  fm (partial mod n)
                  np (some zero? (map fm ps2))]
                (recur
                   (if np i (dec i))
                   (+ n 2)
                   (if np
                      ps
                      (conj ps n)))))))

JVM 味道很浓

这个奇技淫巧,在别的语言中也是凑效的。正则表达式只需支持分组和后向引用。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号