From 98b01afa04cd04796100b217b04f5f5f1b58e63e Mon Sep 17 00:00:00 2001 From: Colin Okay Date: Wed, 8 Jul 2020 19:43:55 -0500 Subject: added examples and readme --- examples.lisp | 74 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 14 deletions(-) (limited to 'examples.lisp') 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. -- cgit v1.2.3