aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples.lisp
diff options
context:
space:
mode:
authorColin Okay <cbeok@protonmail.com>2020-07-08 19:43:55 -0500
committerColin Okay <cbeok@protonmail.com>2020-07-08 19:43:55 -0500
commit98b01afa04cd04796100b217b04f5f5f1b58e63e (patch)
tree9e3bfc461615e9986e13bc7d88ea63563cea7b02 /examples.lisp
parentd7cf8b1aa1daf27bd7b64e5c643b7cca4177571f (diff)
added examples and readme
Diffstat (limited to 'examples.lisp')
-rw-r--r--examples.lisp74
1 files changed, 60 insertions, 14 deletions
diff --git a/examples.lisp b/examples.lisp
index 2893447..83ba5c8 100644
--- a/examples.lisp
+++ b/examples.lisp
@@ -1,16 +1,59 @@
(defpackage #:gtwiwtg.examples
(:use #:cl #:gtwiwtg)
- (:export #:perms #:all-primes))
+ (:export
+ #:perms
+ #:all-primes
+ #:fibs))
(in-package :gtwiwtg.examples)
-;; permutations
+;;; PRIMES ;;;
+(defun prime-p (n)
+ "Naive test for primes."
+ (loop
+ :for x :from 2 :upto (sqrt n)
+ :when (zerop (mod n x)) :do (return nil)
+ :finally (return t)))
+
+(defun all-primes ()
+ "Creates a generator that produces an infinite series of primes."
+ (filter! #'prime-p (range :from 2)))
+
+;; Here is an example of using all-primes to get a list of the 0th,
+;; 10th and 30th prime numbers, indexed starting at 0:
+
+(pick-out '(0 10 30) (all-primes)) ;; (2 31 127)
+
+;; Note that you can PICK-OUT in any order, and repeat too:
+(pick-out '(30 10 0 10) (all-primes)) ;; (127 31 2 31)
+
+;; get the 10 primes after the 20th prime
+
+(take 10 (skip! 20 (all-primes))) ;; (73 79 83 89 97 101 103 107 109 113)
+
+;;; FIBBONACCI NUMBERS ;;;
+
+(defun fibs ()
+ "Creates an infinite series of Fibbonacci numbers."
+ (from-recurrence
+ (lambda (n-1 n-2) (+ n-1 n-2))
+ 1 0))
+
+;; First ten Fibbonacci numbers
+(take 10 (fibs)) ;; (1 2 3 5 8 13 21 34 55 89)
+
+;; Just the 40th Fibbonacci number, indexed from 0
+(car (pick-out '(40) (fibs))) ;; 267914296
+
+
+;;; PERMUTATIONS ;;;
(defun fill-and-insert (idx elem vec buffer)
"A utilty function that modifies BUFFER.
-The length of BUFFER is one greater than the length of VEC.
+The length of BUFFER is assumed to be one greater than the length of
+VEC.
This function fills the first IDX fields of BUFFER with the first IDX
fields of VEC. Fills the field of BUFFER at IDX with ELEM. Fills the
@@ -51,15 +94,18 @@ vector VEC, one at a time."
:element-type (array-element-type vec)))))
(inflate! (lambda (subperm) (thread-through elem subperm)) subperms))))
-;; primes
-
-(defun prime-p (n)
- (loop
- :for x :from 2 :upto (sqrt n)
- :when (zerop (mod n x)) :do (return nil)
- :finally (return t)))
-
-(defun all-primes ()
- (filter! #'prime-p (range :from 1)))
-
+;; In the above, the interesting bit is in the recursive step, and in
+;; the call to inflate. Most of the noise in the above has to do with
+;; the creation of the displaced array (for memory conservation
+;; purposes) that is recursively apssed to perms.
+;; the whole thing could have been written:
+;;
+;; (defun perms (vec)
+;; (if (= 1 (length vec)) (seq (list vec))
+;; (let ((elem (elt vec 0))
+;; (subperms (perms (subseq vec 1))))
+;; (inflate! (lambda (subperm) (thread-through elem subperm))
+;; subperms))))
+;;
+;; which looks a little nicer but is less kind to the heap and to GC.