summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2022-11-26 18:06:19 +0100
committerLeah Neukirchen <leah@vuxu.org>2022-11-26 18:06:19 +0100
commit2a0f96114fb75ecf6975812a041e96f7b9d161c5 (patch)
tree5b6753580edd6aec550f8d00f7177ca1f7d453b9
parentb33a8d20e524ecf57568a3af8e814a7fb3f7dd62 (diff)
downloadmew-2a0f96114fb75ecf6975812a041e96f7b9d161c5.tar.gz
mew-2a0f96114fb75ecf6975812a041e96f7b9d161c5.tar.xz
mew-2a0f96114fb75ecf6975812a041e96f7b9d161c5.zip
add shuffle
-rw-r--r--mew.scm13
-rw-r--r--mew.svnwiki14
-rw-r--r--tests/test.mew5
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 {{<irx>}} uses match data, the result is unspecified.
 
 Mew initializes the {{(chicken random)}} generator from a high entropy source.
 
-<procedure>(rand)<procedure>
+<procedure>(rand)</procedure>
 
 Returns a random real between 0 and 1.
 
-<procedure>(rand N)<procedure>
+<procedure>(rand <N>)</procedure>
 
-Returns a random integer such that 0 <= {{(rand N)}} < {{N}}.
+Returns a random integer such that 0 <= {{(rand <N>)}} < {{<N>}}.
 
-<procedure>(rand N M)<procedure>
+<procedure>(rand <N> <M>)</procedure>
 
-Returns a random integer such that N <= {{(rand M)}} < {{M}}.
+Returns a random integer such that N <= {{(rand <M>)}} < {{<M>}}.
+
+<procedure>(shuffle <vector>)</procedure>
+
+Shuffles the vector {{<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)))