From 2a0f96114fb75ecf6975812a041e96f7b9d161c5 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Sat, 26 Nov 2022 18:06:19 +0100 Subject: add shuffle --- mew.scm | 13 ++++++++++++- mew.svnwiki | 14 +++++++++----- tests/test.mew | 5 +++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/mew.scm b/mew.scm index 1c1674c..c5f1f31 100644 --- a/mew.scm +++ b/mew.scm @@ -17,7 +17,7 @@ odometer one-of op op* per prn proj puts rand range rep - scan scan-right sing? search seq set set-at str slurp + scan scan-right sing? search seq set set-at shuffle str slurp tally-accumulator tbl time while uniq-accumulator unlist until @@ -401,6 +401,17 @@ ((n) (pseudo-random-integer n)) ((n m) (+ n (pseudo-random-integer (- m n)))))) + (define (shuffle v) + (let loop ((i (- (vector-length v) 1))) + (when (positive? i) + (let* ((j (rand (+ i 1))) + (vi (vector-ref v i)) + (vj (vector-ref v j))) + (vector-set! v i vj) + (vector-set! v j vi) + (loop (dec i))))) + v) + (define range (case-lambda (() (make-range-generator 0 +inf.0 1)) diff --git a/mew.svnwiki b/mew.svnwiki index 5c955ed..6898888 100644 --- a/mew.svnwiki +++ b/mew.svnwiki @@ -511,17 +511,21 @@ When the pattern {{}} uses match data, the result is unspecified. Mew initializes the {{(chicken random)}} generator from a high entropy source. -(rand) +(rand) Returns a random real between 0 and 1. -(rand N) +(rand ) -Returns a random integer such that 0 <= {{(rand N)}} < {{N}}. +Returns a random integer such that 0 <= {{(rand )}} < {{}}. -(rand N M) +(rand ) -Returns a random integer such that N <= {{(rand M)}} < {{M}}. +Returns a random integer such that N <= {{(rand )}} < {{}}. + +(shuffle ) + +Shuffles the vector {{}} randomly in-place using a Fisher-Yates shuffle. == Special syntax diff --git a/tests/test.mew b/tests/test.mew index d0b5685..cf84c97 100644 --- a/tests/test.mew +++ b/tests/test.mew @@ -30,6 +30,11 @@ (test #t (<= 2 (rand 2 6))) (test #t (< (rand 2 6) 6))) +(test-group "shuffle" + (test #(1 2 3) (sort (shuffle #(3 2 1)) <)) + (test #f (=? (shuffle #(1 2 3 4 5 6 7 8 9 0)) + (shuffle #(1 2 3 4 5 6 7 8 9 0))))) + (test-group "range" (test '(1 2 3) (into '() (range 1 4))) (test '() (into '() (range 4 1))) -- cgit 1.4.1