Skip to content

Commit

Permalink
Added sorting-routines
Browse files Browse the repository at this point in the history
  • Loading branch information
skx committed Oct 30, 2022
1 parent 5347f1c commit 2924190
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,11 @@ Here the regular expressions will be matched against the name of the file(s) in

A reasonable amount of sample code can be found in the various included examples:

* [test.lisp](test.lisp) shows many things.
* [fibonacci.list](fibonacci.lisp) calculate the first 25 numbers of the Fibonacci sequence.
* [fizzbuzz.lisp](fizzbuzz.lisp) is a standalone sample of solving the fizzbuzz problem.
* [mtest.lisp](mtest.lisp) shows some macro examples.
* [sorting.lisp](sorting.lisp) demonstrates writing & benchmarking sorting-routines.
* [test.lisp](test.lisp) shows many things.

As noted there is a standard-library of functions which are loaded along with any user-supplied script - that library of functions may also provide a useful reference and example of yal-code:

Expand Down
124 changes: 124 additions & 0 deletions sorting.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
;;; sorting.lisp - Demonstrate generating random lists, and sorting them.

;;
;; This example demonstrates creating lists of random (integer)
;; numbers, and sorting them with two different methods.
;;
;; Our random numbers range from -1024 to +1024.
;;
;; We have three sorting methods to test:
;;
;; 1. insert-sort, implemented in lisp.
;;
;; 2. quick-sort, implemented in lisp.
;;
;; 3. sort, implemented in golang
;;


(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)))



;;
;; insertion-sort
;;

(set! insert (fn* (item lst)
(if (nil? lst)
(cons item lst)
(if (> item (car lst))
(cons (car lst) (insert item (cdr lst)))
(cons item lst)))))

(set! insertsort (fn* (lst)
(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))))

(set! list>= (fn* (m list)
(filter list (lambda (n) (! (< n m))))))

(set! list< (fn* (m list)
(filter list (lambda (n) (< n m)))))

(set! qsort (fn* (l)
(if (nil? l)
nil
(append3 (qsort (list< (car l) (cdr l)))
(cons (car l) null)
(qsort (list>= (car l) (cdr l)))))))




;;
;; Now we have defined functions to generate a list of random integers,
;; and we also have our two sorting methods, so we can test things :)
;;
;; Spoiler qsort is the faster lisp sort, but the native golang sort
;; is significantly faster - due to lack of recursion & etc.
;;
(let* (
lst (random:list 512) ; create a random list - 512 elements

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

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)
(lambda (x)
(let* (a (nth isrt x)
b (nth qsrt x)
c (nth gsrt x))

(if (! (eq a b))
(print "List element %d differs!" x))
(if (! (eq b c))
(print "List element %d differs!" x))
(print "%d,%d,%d" a b c))))
(print "All done!")
)

0 comments on commit 2924190

Please sign in to comment.