x! = factorial (x) = x * (x - 1) * (x - 2) * ... 1
factorial (x) = | 1 when x = 0 | x * (factorial (x - 1)) when x > 0
(defun factorial (x) " computes the factorial of any integer number " (if (zerop x) 1 (* x (factorial (1- x)))))
(factorial 6) -> 720
(trace factorial) -> (FACTORIAL) (factorial 6) 1> (FACTORIAL 6) 2> (FACTORIAL 5) 3> (FACTORIAL 4) 4> (FACTORIAL 3) 5> (FACTORIAL 2) 6> (FACTORIAL 1) 7> (FACTORIAL 0) <7 (FACTORIAL 1) <6 (FACTORIAL 1) <5 (FACTORIAL 2) <4 (FACTORIAL 6) <3 (FACTORIAL 24) <2 (FACTORIAL 120) <1 (FACTORIAL 720) 720
(untrace factorial)
;;; the empty association list (defvar *factorial-a-list* '()) (defun factorial (x) " computes the factorial of any integer number " (if (assoc x *factorial-a-list*) (cdr (assoc x *factorial-a-list*)) (let ((new (if (and (<= x 1)(plusp x)) 1 (* x (factorial (1- x)))))) (push (cons x new) *factorial-a-list*) new)))
(factorial 6) -> 720 *factorial-a-list* ((6 . 720) (5 . 120) (4 . 24) (3 . 6) (2 . 2) (1 . 1))
fibbobaci (x) = fibonacci (x - 2) + fibonacci (x - 1) fibbobaci (x) = | 1 when x <= 2 | fibonacci (x - 2) + fibonacci (x - 1) when x > 2
(defun fibonacci (x) " computes the fibonacci number of x " (if (<= x 2) 1 (+ (fibonacci (- x 2))(fibonacci (1- x))))) (loop for i from 1 to 7 do (print (fibonacci i)))
(trace fibonacci) (fibonacci 7) 1> (fibonacci 7) 2> (fibonacci 5) 3> (fibonacci 3) 4> (fibonacci 1) <4 (fibonacci 1) 4> (fibonacci 2) <4 (fibonacci 1) <3 (fibonacci 2) 3> (fibonacci 4) 4> (fibonacci 2) <4 (fibonacci 1) 4> (fibonacci 3) 5> (fibonacci 1) <5 (fibonacci 1) 5> (fibonacci 2) <5 (fibonacci 1) <4 (fibonacci 2) <3 (fibonacci 3) <2 (fibonacci 5) 2> (fibonacci 6) 3> (fibonacci 4) 4> (fibonacci 2) <4 (fibonacci 1) 4> (fibonacci 3) 5> (fibonacci 1) <5 (fibonacci 1) 5> (fibonacci 2) <5 (fibonacci 1) <4 (fibonacci 2) <3 (fibonacci 3) 3> (fibonacci 5) 4> (fibonacci 3) 5> (fibonacci 1) <5 (fibonacci 1) 5> (fibonacci 2) <5 (fibonacci 1) <4 (fibonacci 2) 4> (fibonacci 4) 5> (fibonacci 2) <5 (fibonacci 1) 5> (fibonacci 3) 6> (fibonacci 1) <6 (fibonacci 1) 6> (fibonacci 2) <6 (fibonacci 1) <5 (fibonacci 2) <4 (fibonacci 3) <3 (fibonacci 5) <2 (fibonacci 8) <1 (fibonacci 13) 13 (untrace fibonacci)
;;; the empty association list (defvar *fibonacci-a-list* '()) (defun fibonacci (x) " computes the fibonacci number of x " (if (assoc x *fibonacci-a-list*) (cdr (assoc x *fibonacci-a-list*)) (let ((new (if (<= x 2) 1 (+ (fibonacci (- x 2))(fibonacci (1- x)))))) (push (cons x new) *fibonacci-a-list*) new)))
(fibonacci 7) -> 13 *fibonacci-a-list* ((7 . 13) (6 . 8) (5 . 5) (4 . 3) (3 . 2) (2 . 1) (1 . 1))
(defun retrograde (list-of-notes) (if (null list-of-notes) nil ;;; 1 (append (last list-of-notes) ;;; 2 (retrograde (butlast list-of-notes))))) ;;; 3
(retrograde '(a4 c5 b5)) -> (B5 C5 A4)
(trace retrograde) (retrograde '(a4 c5 b5)) 1> (RETROGRADE (A4 C5 B5)) 2> (RETROGRADE (A4 C5)) 3> (RETROGRADE (A4)) 4> (RETROGRADE NIL) <4 (RETROGRADE NIL) <3 (RETROGRADE (A4)) <2 (RETROGRADE (C5 A4)) <1 (RETROGRADE (B5 C5 A4)) (B5 C5 A4) (untrace retrograde)
(defun intev-func (list-of-notes) (if (null (rest list-of-notes)) NIL (cons (- (second list-of-notes) (first list-of-notes)) (intev-func (rest list-of-notes))))) ;;; this macro calls the interv-func with MIDI note numbers (defmacro intervals (list-of-notes) `(intev-func (mapcar #'degree ,list-of-notes)))
(intervals '(c3 g4 a7)) -> (19 38)
(defun invert-func (intervs notes) (if (null intervs) (nreverse notes) (let ((new (- (first notes) (first intervs)))) (push new notes) (invert-func (rest intervs) notes)))) (defmacro inversion (list-of-notes) `(mapcar #'note (invert-func (intervals ,list-of-notes) (list (degree (first ,list-of-notes))))))
(trace invert-func) (inversion '(c4 d4 e4)) 1> (INVERT-FUNC (2 2) (60)) 2> (INVERT-FUNC (2) (58 60)) 3> (INVERT-FUNC NIL (56 58 60)) <3 (INVERT-FUNC (60 58 56)) <2 (INVERT-FUNC (60 58 56)) <1 (INVERT-FUNC (60 58 56)) (C4 AS3 GS3)
(defun degree-l (l) (mapcar #'degree l)) (defun note-l (l) (mapcar #'note l)) (defun all-forms (raw) (let*((orig (degree-l raw)) (inv (degree-l (inversion raw))) (retro (degree-l (retrograde raw))) (retro-inv (degree-l (inversion (retrograde raw)))) (o-list nil) (i-list nil) (r-list nil) (ri-list nil)) (dotimes (i 12) (push (mapcar #'(lambda (x) (+ x i)) orig) o-list) (push (mapcar #'(lambda (x) (+ x i)) inv) i-list) (push (mapcar #'(lambda (x) (+ x i)) retro) r-list) (push (mapcar #'(lambda (x) (+ x i)) retro-inv) ri-list)) (list (mapcar #'note-l (nreverse o-list)) (mapcar #'note-l (nreverse i-list)) (mapcar #'note-l (nreverse r-list)) (mapcar #'note-l (nreverse ri-list)))))
(all-forms '(c4 cs4 e4 ef4 d4 b4 fs4 g4 bf4 a4 af4 f4)) (((C4 CS4 E4 DS4 D4 B4 FS4 G4 AS4 A4 GS4 F4) ;;; original (CS4 D4 F4 E4 DS4 C5 G4 GS4 B4 AS4 A4 FS4) (D4 DS4 FS4 F4 E4 CS5 GS4 A4 C5 B4 AS4 G4) (DS4 E4 G4 FS4 F4 D5 A4 AS4 CS5 C5 B4 GS4) (E4 F4 GS4 G4 FS4 DS5 AS4 B4 D5 CS5 C5 A4) (F4 FS4 A4 GS4 G4 E5 B4 C5 DS5 D5 CS5 AS4) (FS4 G4 AS4 A4 GS4 F5 C5 CS5 E5 DS5 D5 B4) (G4 GS4 B4 AS4 A4 FS5 CS5 D5 F5 E5 DS5 C5) (GS4 A4 C5 B4 AS4 G5 D5 DS5 FS5 F5 E5 CS5) (A4 AS4 CS5 C5 B4 GS5 DS5 E5 G5 FS5 F5 D5) (AS4 B4 D5 CS5 C5 A5 E5 F5 GS5 G5 FS5 DS5) (B4 C5 DS5 D5 CS5 AS5 F5 FS5 A5 GS5 G5 E5)) ((C4 B3 GS3 A3 AS3 CS3 FS3 F3 D3 DS3 E3 G3) ;;; inversion (CS4 C4 A3 AS3 B3 D3 G3 FS3 DS3 E3 F3 GS3) (D4 CS4 AS3 B3 C4 DS3 GS3 G3 E3 F3 FS3 A3) (DS4 D4 B3 C4 CS4 E3 A3 GS3 F3 FS3 G3 AS3) (E4 DS4 C4 CS4 D4 F3 AS3 A3 FS3 G3 GS3 B3) (F4 E4 CS4 D4 DS4 FS3 B3 AS3 G3 GS3 A3 C4) (FS4 F4 D4 DS4 E4 G3 C4 B3 GS3 A3 AS3 CS4) (G4 FS4 DS4 E4 F4 GS3 CS4 C4 A3 AS3 B3 D4) (GS4 G4 E4 F4 FS4 A3 D4 CS4 AS3 B3 C4 DS4) (A4 GS4 F4 FS4 G4 AS3 DS4 D4 B3 C4 CS4 E4) (AS4 A4 FS4 G4 GS4 B3 E4 DS4 C4 CS4 D4 F4) (B4 AS4 G4 GS4 A4 C4 F4 E4 CS4 D4 DS4 FS4)) ((F4 GS4 A4 AS4 G4 FS4 B4 D4 DS4 E4 CS4 C4) ;;; retrograde (FS4 A4 AS4 B4 GS4 G4 C5 DS4 E4 F4 D4 CS4) (G4 AS4 B4 C5 A4 GS4 CS5 E4 F4 FS4 DS4 D4) (GS4 B4 C5 CS5 AS4 A4 D5 F4 FS4 G4 E4 DS4) (A4 C5 CS5 D5 B4 AS4 DS5 FS4 G4 GS4 F4 E4) (AS4 CS5 D5 DS5 C5 B4 E5 G4 GS4 A4 FS4 F4) (B4 D5 DS5 E5 CS5 C5 F5 GS4 A4 AS4 G4 FS4) (C5 DS5 E5 F5 D5 CS5 FS5 A4 AS4 B4 GS4 G4) (CS5 E5 F5 FS5 DS5 D5 G5 AS4 B4 C5 A4 GS4) (D5 F5 FS5 G5 E5 DS5 GS5 B4 C5 CS5 AS4 A4) (DS5 FS5 G5 GS5 F5 E5 A5 C5 CS5 D5 B4 AS4) (E5 G5 GS5 A5 FS5 F5 AS5 CS5 D5 DS5 C5 B4)) ((F4 D4 CS4 C4 DS4 E4 B3 GS4 G4 FS4 A4 AS4) ;;; retrograde-inversion (FS4 DS4 D4 CS4 E4 F4 C4 A4 GS4 G4 AS4 B4) (G4 E4 DS4 D4 F4 FS4 CS4 AS4 A4 GS4 B4 C5) (GS4 F4 E4 DS4 FS4 G4 D4 B4 AS4 A4 C5 CS5) (A4 FS4 F4 E4 G4 GS4 DS4 C5 B4 AS4 CS5 D5) (AS4 G4 FS4 F4 GS4 A4 E4 CS5 C5 B4 D5 DS5) (B4 GS4 G4 FS4 A4 AS4 F4 D5 CS5 C5 DS5 E5) (C5 A4 GS4 G4 AS4 B4 FS4 DS5 D5 CS5 E5 F5) (CS5 AS4 A4 GS4 B4 C5 G4 E5 DS5 D5 F5 FS5) (D5 B4 AS4 A4 C5 CS5 GS4 F5 E5 DS5 FS5 G5) (DS5 C5 B4 AS4 CS5 D5 A4 FS5 F5 E5 G5 GS5) (E5 CS5 C5 B4 D5 DS5 AS4 G5 FS5 F5 GS5 A5)))
©1996-98 by Juan Pampin, juan@ccrma.stanford.edu