diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-08-24 06:37:19 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-08-24 06:37:19 -0700 |
commit | 4e3e4e1ccc60331ff8ff4c1c139e9da3c95e2272 (patch) | |
tree | 05869854697db857750edeb23b091c39983a4e1e | |
parent | 87af2fde6249070addbed571482ddae251d90161 (diff) | |
download | txr-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.
-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 ]]) |