From 5db534fdfba41419c72faf79230b0999a04e38bb Mon Sep 17 00:00:00 2001 From: Steve Kemp Date: Wed, 2 Nov 2022 06:18:36 +0200 Subject: [PATCH 1/2] Updated our append/reverse implementations. Specifically we wanted our append to be more standard. This will close #74, once merged. --- stdlib/stdlib/stdlib.lisp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/stdlib/stdlib/stdlib.lisp b/stdlib/stdlib/stdlib.lisp index 0fed167..817a7aa 100644 --- a/stdlib/stdlib/stdlib.lisp +++ b/stdlib/stdlib/stdlib.lisp @@ -81,19 +81,18 @@ See-also: apply, apply-pairs" acc (reduce (cdr xs) f (f acc (car xs)))))) -; O(n^2) behavior with linked lists -(set! append (fn* (xs:list el) - "Append the given element to the specified list." - (if (nil? xs) - (list el) - (cons (car xs) (append (cdr xs) el))))) - - -(set! reverse (fn* (x:list) - "Return a list containing all values in the supplied list, in reverse order." - (if (nil? x) - () - (append (reverse (cdr x)) (car x))))) +(set! append (fn* (lst item) + "Append the given value to the specified list. If the list is empty just return the specified item." + (if (nil? lst) + item + (cons (car lst) (append (cdr lst) item))))) + + +(set! reverse (fn* (l) + "Reverse the contents of the specified list." + (if (nil? l) + nil + (append (reverse (cdr l)) (list (car l)))))) ;; Get the first N items from a list. From 3f8099f91a30287f87f8e028e5418713089c323b Mon Sep 17 00:00:00 2001 From: Steve Kemp Date: Wed, 2 Nov 2022 06:19:14 +0200 Subject: [PATCH 2/2] Updated our sorting now we have a better (append..) We're no longer needing to use a local append-like function, as the standard one will work. Updated the sorting to show all entries, and to be a bit cleaner too. --- sorting.lisp | 71 ++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/sorting.lisp b/sorting.lisp index a113f4f..6197993 100644 --- a/sorting.lisp +++ b/sorting.lisp @@ -2,9 +2,7 @@ ;; ;; This example demonstrates creating lists of random (integer) -;; numbers, and sorting them with two different methods. -;; -;; Our random numbers range from -1024 to +1024. +;; numbers, and then sorting them. ;; ;; We have three sorting methods to test: ;; @@ -16,18 +14,14 @@ ;; -(set! random:number (fn* () - "Return a random number from -1024 to 1024" - (let* (sign 1 - max 1024) - ; optionally this might be negative - (if (= 0 (random 2)) - (set! sign -1)) - (* sign (random max))))) - -(set! random:list (fn* (n) - "Return a random list of numbers, of the length n." - (map (seq n) random:number))) +(set! random:list (fn* (n max) + "Return a list of random numbers, of the length n, ranging from -max to +max." + (map (nat n) (lambda (n) + (let* (sign 1) + ; optionally this might be negative + (if (= 0 (random 2)) + (set! sign -1)) + (* sign (random max))))))) @@ -36,6 +30,7 @@ ;; (set! insert (fn* (item lst) + "Insert the specified item into the given list, in the correct (sorted) order." (if (nil? lst) (cons item lst) (if (> item (car lst)) @@ -43,34 +38,32 @@ (cons item lst))))) (set! insertsort (fn* (lst) + "An insert-sort implementation. For each item in the given list, use insert to place it into the list in the correct order." (if (nil? lst) nil (insert (car lst) (insertsort (cdr lst)))))) - ;; ;; quick-sort ;; -;; append in our standard library makes "(list b)" not "b". Changing that -;; would cause issues, so I'm duplicating here. -(set! append2 (fn* (a b) - (if (nil? a) - b - (cons (car a) (append2 (cdr a) b) )))) - (set! append3 (fn* (a b c) - (append2 a (append2 b c)))) + "Like append, but with three items, not two." + (append a (append b c)))) (set! list>= (fn* (m list) + "Return all items of the given list which are greater than, or equal to, the specified item." (filter list (lambda (n) (! (< n m)))))) + (set! list< (fn* (m list) + "Return all items of the given list which are less than the specified item." (filter list (lambda (n) (< n m))))) (set! qsort (fn* (l) + "A recursive quick-sort implementation." (if (nil? l) nil (append3 (qsort (list< (car l) (cdr l))) @@ -88,28 +81,30 @@ ;; is significantly faster - due to lack of recursion & etc. ;; (let* ( - lst (random:list 512) ; create a random list - 512 elements + count 512 ; how many items to work with + lst (random:list count 4096) ; create a random list of integers + ; between -4096 and +4096. - bis (ms) ; before-insert-sort take a timestamp - isrt (insertsort lst) ; run insert-sort - ais (ms) ; after insert-sort take a timestamp + bis (ms) ; before-insert-sort take a timestamp + isrt (insertsort lst) ; run insert-sort + ais (ms) ; after insert-sort take a timestamp - bqs (ms) ; before-quick-sort take a timestamp - qsrt (qsort lst) ; run the quick-sort - aqs (ms) ; after-quick-sort take a timestamp + bqs (ms) ; before-quick-sort take a timestamp + qsrt (qsort lst) ; run the quick-sort + aqs (ms) ; after-quick-sort take a timestamp - bgs (ms) ; before-go-sort take a timestamp - gsrt (sort lst) ; run the go sort - ags (ms) ; after-go-sort take a timestamp + bgs (ms) ; before-go-sort take a timestamp + gsrt (sort lst) ; run the go sort + ags (ms) ; after-go-sort take a timestamp ) (print "insert sort took %d ms " (- ais bis)) (print "quick sort took %d ms " (- aqs bqs)) (print "go sort took %d ms " (- ags bgs)) ; a simple sanity-check of the results - (print "Testing results - first 20 - to make sure all sorts were equal") - (print "insert-sort,quick-sort,go-sort") - (apply (nat 20) + (print "Testing results, to ensure each sort produced identical results.") + (print "offset,insert-sort,quick-sort,go-sort") + (apply (seq count) (lambda (x) (let* (a (nth isrt x) b (nth qsrt x) @@ -119,6 +114,6 @@ (print "List element %d differs!" x)) (if (! (eq b c)) (print "List element %d differs!" x)) - (print "%d,%d,%d" a b c)))) + (print "%d,%d,%d,%d" x a b c)))) (print "All done!") )