Last active
June 22, 2021 02:51
-
-
Save paomian/1f30bcda891ab9679001847f9bc367f6 to your computer and use it in GitHub Desktop.
stream
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;不得不说,这思想很牛,但是理解起来也很绕,不知道这种代码到底是好还是不好。。。 | |
;;想想不用这种方法怎么来实现这个功能,应该是用一个额外的表记录下所有前面的素数,然后用 (map (fn [x] (some (fn [y] (not-zero?(mod x y))) [primes list])) strems) | |
(defmacro my-delay [body] | |
`(fn [] ~body)) | |
(defn my-force [f] | |
(f)) | |
(def the-empty-stream []) | |
(def stream-null? empty?) | |
(defmacro cons-stream [x y] | |
`[~x (my-delay ~y)]) | |
(defn stream-car [x] | |
(first x)) | |
(defn stream-cdr [x] | |
(my-force (second x))) | |
(defn stream-ref [s n] | |
(if (= n 0) | |
(stream-car s) | |
(stream-ref (stream-cdr s) (dec n)))) | |
#_(defn stream-map [f s] | |
(println "hhh" s) | |
(if (empty? s) | |
the-empty-stream | |
(cons-stream (f (stream-car s)) | |
(stream-map f (stream-cdr s))))) | |
(defn stream-map [f & s] | |
(if (empty? (first s)) | |
the-empty-stream | |
(cons-stream | |
(apply f (map stream-car s)) | |
(apply stream-map f | |
(map stream-cdr s))))) | |
(defn stream-for-each [f s] | |
(if (stream-null? s) | |
'done | |
(do (f (stream-car s)) | |
(stream-for-each f (stream-cdr s))))) | |
(defn display-line [x] | |
(println x)) | |
(defn display-stream [s] | |
(stream-for-each display-line s)) | |
(defn stream-enumerate-interval [low high] | |
(if (> low high) | |
the-empty-stream | |
(cons-stream low (stream-enumerate-interval (inc low) high)))) | |
(defn stream-filter [pred stream] | |
(cond (stream-null? stream) the-empty-stream | |
(pred (stream-car stream)) (cons-stream (stream-car stream) | |
(stream-filter pred (stream-cdr stream))) | |
:else (stream-filter pred (stream-cdr stream)))) | |
(defn memo-proc [proc] | |
(let [already-run? (volatile! false) | |
result (volatile! false)] | |
(fn [] | |
(if (not @already-run?) | |
(do (vreset! result (proc)) | |
(vreset! already-run? true) | |
@result) | |
result)))) | |
(defn integers-starting-from [n] | |
(cons-stream n (integers-starting-from (inc n)))) | |
(def integers (integers-starting-from 1)) | |
(def no-sevens (stream-filter (fn [x] (not= 0 (mod x 7))) | |
integers)) | |
(defn divisible? [n m] | |
(zero? (mod n m))) | |
(defn sieve [stream] | |
(cons-stream | |
(stream-car stream) | |
(sieve (stream-filter | |
(fn [x] (not (divisible? x (stream-car stream)))) | |
(stream-cdr stream))))) | |
;;(def primes (sieve (integers-starting-from 2))) | |
(def ones (cons-stream 1 ones)) | |
(defn add-streams [s1 s2] | |
(stream-map + s1 s2)) | |
(def integers (cons-stream 1 (add-streams ones integers))) | |
(def fibs (cons-stream 0 (cons-stream 1 (add-streams (stream-cdr fibs) fibs)))) | |
(defn scale-stream [stream factor] | |
(stream-map (fn [x] (* x factor)) stream)) | |
(def my-double (cons-stream 1 (scale-stream my-double 2))) | |
(declare prime?) | |
(def primes (cons-stream 2 (stream-filter prime? (integers-starting-from 3)))) | |
(defn prime? [n] | |
(let [iter (fn iter [ps] | |
(cond (> (square (stream-car ps)) n) true | |
(divisible? n (stream-car ps)) false | |
:else (iter (stream-cdr ps))))] | |
(iter primes))) | |
(-> primes (stream-ref 50)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment