Last active
February 14, 2018 00:42
-
-
Save dmkolobov/ab51f2f616ff867554204ecd7e8d8dd0 to your computer and use it in GitHub Desktop.
exercises.clj
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
(defrecord Person [name employees]) ;; Defines a Person product type. | |
;; Fields are accessed via (:name person) (:employees :person) | |
(defn employees-list | |
"Returns a list of all people directly or indirectly employed by 'person'." | |
[person] | |
(apply concat ;; (apply f x1 ... xn [y1 ... yn]) => (apply f x1 ... xn y1 ... yn) | |
[(:name person)] ;; a single-element vector containing the name of 'person' | |
(map employees-list (:employees person)))) | |
(defn lazy-primes | |
([] | |
(lazy-primes (drop 2 (range)) | |
[])) | |
([[x & xs] primes] | |
(lazy-seq ;; (lazy-seq & body) => body is evaluated once and memoized. returns a lazy sequence. | |
(if (some (fn [p] (= 0 (mod x p))) | |
primes) | |
(lazy-primes xs primes) | |
(cons x | |
(lazy-primes xs (conj primes x))))))) | |
(def the-primes (lazy-primes)) | |
(take 10 the-primes) ;; => (2 3 5 7 11 13 17 19 23 29) | |
;; This actually evaluates 32 elements of 'the-primes' and caches them. | |
;; also, it turns out we can "short-circuit" the strict evaluation of Clojure's 'reduce'(fold) function | |
;; to allow folding inifinite lists. However, we cannot build a new infinite list in this way. | |
(defn primes | |
"Returns a list of primes up to n." | |
[n] | |
(reduce (fn [primes x] | |
(cond (= n (count primes)) ;; count is O(1) for vectors | |
(reduced primes) ;; stops the fold and returns primes. Needed because clojure 'reduce' | |
;; is strict. | |
(some (fn [p] (= 0 (mod x p))) | |
primes) ;; (some pred s) returns true if pred is true for any element of s | |
primes | |
:default (conj primes x))) ;; (conj [x1 ... xn] y) => [x1 ... xn y] | |
[] ;; initial value, the empty vector | |
(drop 2 (range)))) ;; (range) creates an infinite lazy sequence (0, 1, 2, ...) | |
;; The dropping 2 transforms this sequence into (2, 3, 4, ...) | |
(primes 10) ;; => [2 3 5 7 11 13 17 19 23 29] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment