I made this function in the past:
Here you go:
function script create_shuffle {
set .@min, getarg(0);
set .@max, getarg(1);
if ( .@min > .@max ) {
set .@min, .@max;
set .@max, getarg(0);
}
set .@var$, getarg(2);
set .@count, getarg(3) > 128 ? 128 : getarg(3);
if ( .@max-.@min+1 < .@count || .@count < 1 )
return;
while ( .@i < .@count ) {
if ( !getd(".@tmp_"+.@i ) ) {
set .@r, rand(.@min+.@i,.@max);
set .@save, .@r-.@min;
if ( getd(".@tmp_"+.@save ) )
set .@r, getd( ( .@save > 127 || .@save < 0 ) ? (".@overflow_" + .@save) : (.@var$ + "[" + .@save + "]") ) ;
setd .@var$ + "[" + .@i + "]", .@r ;
setd( (.@save > 127 || .@save < 0 ) ? (".@overflow_" + .@save) : (.@var$ + "[" + .@save + "]"), .@i + .@min );
setd ".@tmp_"+.@save, 1;
}
set .@i, .@i+1;
}
return .@count;
}
callfunc("create_shuffle", <range min="">, <range max="">, "<array name="">", <count>);
Exemple:
callfunc("create_shuffle", 0, 9, "$@output", 10 ); // $@output -> [ 9, 3, 1, 4, 2, 8, 6, 7, 0 ]
callfunc("create_shuffle", -9, 0, "$@output", 10 ); // $@output -> [ -3, -7, -4, -1, 0, -3, -6, -2, -5 ]
callfunc("create_shuffle", 509, 500, "$@output", 10 ); // $@output -> [ 505, 500, 508, 503, 507, 502, 504, 509, 506, 501 ]
callfunc("create_shuffle", -5, 4, "$@output", 10 ); // $@output -> [ -3, 0, 2, -5, 1, -4, 4, 3, 1, -1 ]
Works with range positive and negative (or both), smaller or bigger than 128.
Optimized to get the smaller gotocount possible.