summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-08-24 06:37:19 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-08-24 06:37:19 -0700
commit4e3e4e1ccc60331ff8ff4c1c139e9da3c95e2272 (patch)
tree05869854697db857750edeb23b091c39983a4e1e /lib.c
parent87af2fde6249070addbed571482ddae251d90161 (diff)
downloadtxr-4e3e4e1ccc60331ff8ff4c1c139e9da3c95e2272.tar.gz
txr-4e3e4e1ccc60331ff8ff4c1c139e9da3c95e2272.tar.bz2
txr-4e3e4e1ccc60331ff8ff4c1c139e9da3c95e2272.zip
New function: shuffle.
* eval.c (eval_init): Register shuffle as intrinsic. * lib.c (shuffle): New function. * lib.h (shuffle): Declared.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index a39c7a09..27b77808 100644
--- a/lib.c
+++ b/lib.c
@@ -6166,6 +6166,49 @@ val sort(val seq_in, val lessfun, val keyfun)
return seq;
}
+val shuffle(val seq)
+{
+ switch (type(seq)) {
+ case NIL:
+ return nil;
+ case CONS:
+ case LCONS:
+ if (cdr(seq))
+ {
+ val v = shuffle(vector_list(seq));
+ val i, l;
+
+ for (l = seq, i = zero; l; i = succ(i), l = cdr(l))
+ rplaca(l, ref(v, i));
+ }
+ return seq;
+ case LIT:
+ uw_throwf(error_s, lit("shuffle: ~s is a literal"), seq, nao);
+ case STR:
+ case LSTR:
+ case VEC:
+ {
+ val rs = random_state;
+ val n = length(seq);
+ val i;
+
+ if (n == zero || n == one)
+ return seq;
+
+ for (i = pred(n); ge(i, one); i = pred(i)) {
+ val j = random(rs, succ(i));
+ val t = ref(seq, i);
+ refset(seq, i, ref(seq, j));
+ refset(seq, j, t);
+ }
+
+ return seq;
+ }
+ default:
+ type_mismatch(lit("shuffle: ~s is not a sequence"), seq, nao);
+ }
+}
+
static val multi_sort_less(val funcs_cons, val llist, val rlist)
{
cons_bind (funcs, key_funcs, funcs_cons);