View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000560 | LDMud | Efuns | public | 2008-08-13 14:45 | 2010-02-13 03:40 |
Reporter | Largo | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | always |
Status | new | Resolution | open | ||
Summary | 0000560: new efun to randomize array contents | ||||
Description | Hey guys, I've written a small new efun named randomize_array() to replace some of these constructs with sort_array() to achieve an array randomization. Maybe you're interested in it, patch is attached. | ||||
Additional Information | Note that small p_int -> size_t change in array.h: It's not needed by the patch, but using size_t in this place made more sense to me. | ||||
Tags | ldmud-extensions | ||||
Attached Files | shuffle_array.diff (3,442 bytes)
Index: version.sh =================================================================== --- version.sh (Revision 2394) +++ version.sh (Arbeitskopie) @@ -17,7 +17,7 @@ # A timestamp, to be used by bumpversion and other scripts. # It can be used, for example, to 'touch' this file on every build, thus # forcing revision control systems to add it on every checkin automatically. -version_stamp="2007-10-14 12:18:07" +version_stamp="So 17. Aug 14:55:45 CEST 2008" # The version number information version_micro=716 Index: array.c =================================================================== --- array.c (Revision 2394) +++ array.c (Arbeitskopie) @@ -69,6 +69,7 @@ #include "mempools.h" #include "mstrings.h" #include "object.h" +#include "random.h" #include "stdstrings.h" #include "simulate.h" #include "svalue.h" @@ -2806,6 +2807,55 @@ return sp; } /* f_transpose_array() */ +/*-------------------------------------------------------------------------*/ +svalue_t * +f_shuffle_array (svalue_t *sp) + +/* EFUN shuffle_array() + * + * mixed *shuffle_array (mixed *arr); + * + * shuffle_array ( ({1,2,3}) ) + * => ({3,1,2}) + * => ({2,3,1}) + * => ... + * + * shuffle_array() applied to an array results in an array of + * randomly arranged elements. + */ + +{ + vector_t *v; /* Input vector */ + vector_t *w; /* Output vector */ + size_t size; /* size of <v> */ + size_t i; + svalue_t *pos, *next, tmp; + + /* Get and test the arguments */ + v = sp->u.vec; + + if ( (size = VEC_SIZE(v)) < 2) + return sp; + + /* Allocate and fill the result vector */ + w = slice_array(v, 0, size - 1); + free_array(v); + + /* shuffle the array elements */ + for (pos = w->item, i = size; i-- > 0; ++pos) + { + next = w->item + random_number(size - i); + tmp = *next; + transfer_svalue_no_free(next, pos); + transfer_svalue_no_free(pos, &tmp); + } + + /* Clean up and return the result */ + put_array(sp, w); + + return sp; +} /* f_shuffle_array() */ + /*=========================================================================*/ /* EFUN unique_array() Index: array.h =================================================================== --- array.h (Revision 2394) +++ array.h (Arbeitskopie) @@ -60,7 +60,7 @@ */ struct vector_s { - p_int size; /* Number of contained elements */ + size_t size; /* Number of contained elements */ p_int ref; /* Number of references */ #ifdef DEBUG p_int extra_ref; /* Second refcount, used to check .ref. */ @@ -119,6 +119,7 @@ extern svalue_t *v_sort_array(svalue_t *sp, int num_arg); extern svalue_t *x_map_array(svalue_t *sp, int num_arg); extern svalue_t *f_transpose_array(svalue_t *sp); +extern svalue_t *f_shuffle_array(svalue_t *sp); extern svalue_t *v_filter_objects(svalue_t *sp, int num_arg); extern svalue_t *v_map_objects(svalue_t *sp, int num_arg); Index: func_spec =================================================================== --- func_spec (Revision 2394) +++ func_spec (Arbeitskopie) @@ -437,6 +437,7 @@ mixed *map_objects(mixed *, string, ...); mixed *sort_array(mixed *,string|closure, ...); mixed *transpose_array(mixed *); +mixed *shuffle_array(mixed *); mixed *unique_array(mixed *, string|closure, ...); mixed filter(mapping|mixed *|string, string|closure|mapping, ...); | ||||
External Data (URL) | |||||
|
I have no objection to this per se, but this is easy to implement with an sefun like this: mixed *shuffle_array(mixed *a) { a = copy(a); for (int i = sizeof(a); i; ) { int j = random(i--); mixed t = a[i]; a[i] = a[j]; a[j] = t; } return a; } I prefer the name shuffle_array (or maybe just shuffle). Also, the algorithm in the patch isn't quite correct - random_number(size) should be random_number(size - i) for fair shuffling. |
|
alright, useful or not, I adapted the patch to solve the issues. |
|
I am not sure, if we should it as efun, because it does seem to be used so regularly or to be time-critical. But it might well be useful, I know a few places in our mudlib, which do a similar thing. Maybe we can include a collection of contributed sefuns? Either directly in the driver or in a 'unofficial ldmud extensions' (which could be in LPC as well as in C)? |
|
For now I added the patch to http://github.com/zesstra/ldmud-extensions in hope that people find it there. |
Date Modified | Username | Field | Change |
---|---|---|---|
2008-08-13 14:45 | Largo | New Issue | |
2008-08-13 14:45 | Largo | File Added: randomize_array.diff | |
2008-08-14 03:23 | fufu | Note Added: 0000757 | |
2008-08-17 07:02 | Largo | File Added: shuffle_array.diff | |
2008-08-17 07:03 | Largo | Note Added: 0000759 | |
2008-08-17 08:54 | fufu | File Deleted: randomize_array.diff | |
2008-08-17 08:54 | fufu | File Deleted: shuffle_array.diff | |
2008-08-17 08:55 | Largo | File Added: shuffle_array.diff | |
2009-10-08 07:40 | zesstra | Note Added: 0001516 | |
2010-02-13 03:40 | zesstra | Note Added: 0001719 | |
2010-02-15 17:57 | zesstra | Tag Attached: ldmud-extensions |