Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated our append/reverse implementations. #77

Merged
merged 2 commits into from
Nov 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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