diff options
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | lib.c | 43 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | txr.1 | 21 |
4 files changed, 66 insertions, 0 deletions
@@ -4543,6 +4543,7 @@ void eval_init(void) reg_fun(intern(lit("prop"), user_package), func_n2(getplist)); reg_fun(intern(lit("merge"), user_package), func_n4o(merge_wrap, 2)); reg_fun(intern(lit("sort"), user_package), func_n3o(sort, 1)); + reg_fun(intern(lit("shuffle"), user_package), func_n1(shuffle)); reg_fun(intern(lit("find"), user_package), func_n4o(find, 2)); reg_fun(intern(lit("multi-sort"), user_package), func_n3o(multi_sort, 2)); reg_fun(intern(lit("find-if"), user_package), func_n3o(find_if, 2)); @@ -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); @@ -835,6 +835,7 @@ val mapdo(val fun, val list); val interpose(val sep, val seq); val merge(val list1, val list2, val lessfun, val keyfun); val sort(val seq, val lessfun, val keyfun); +val shuffle(val seq); val multi_sort(val lists, val funcs, val key_funcs); val sort_group(val seq, val keyfun, val lessfun); val unique(val seq, val keyfun, struct args *hashv_args); @@ -19544,6 +19544,27 @@ For strings and vectors, .code sort is not stable. +.coNP Function @ shuffle +.synb +.mets (shuffle << sequence ) +.syne +.desc +The +.code shuffle +function pseudo-randomly rearranges the elements of +.metn sequence . +This is performed in place: +.meta sequence +object is modified. + +The return value is +.meta sequence +itself. + +The rearrangement depends on pseudo-random numbers obtained from the +.code rand +function. + .coNP Function @ sort-group .synb .mets (sort-group < sequence >> [ keyfun <> [ lessfun ]]) |