Skip to content

Commit

Permalink
Merge pull request #77 from skx/74-append
Browse files Browse the repository at this point in the history
Updated our append/reverse implementations.
  • Loading branch information
skx authored Nov 2, 2022
2 parents 561aeaa + 3f8099f commit 9713f00
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 51 deletions.
71 changes: 33 additions & 38 deletions sorting.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
;;
Expand All @@ -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)))))))



Expand All @@ -36,41 +30,40 @@
;;

(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))
(cons (car lst) (insert item (cdr lst)))
(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)))
Expand All @@ -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)
Expand All @@ -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!")
)
25 changes: 12 additions & 13 deletions stdlib/stdlib/stdlib.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 9713f00

Please sign in to comment.