Here you'll get Flash (AS3), haXe, JavaScript, PHP, Perl, and Python ports of my continuous shuffled sequence algorithm. As usual the code is available under a Zero-clause BSD-style license, which means you can use it in any way you like.
All implementations utilize an un-seeded default source of randomness. If determinism is required, you'll only need to hand over a PRNG and use that one instead. Or hand the seed over and initialize the PRNG with that one as the original Java version did it.
If you port it to other languages or if you modify it a bit (e.g. as outlined above), you'll have to verify that it works correctly. Fortunately testing it isn't that hard. E.g. if you add "X" and "O" and call next four times you should receive one of the following sequences:
If you get a sequence which wasn't listed above or not all of those permutations (in a loop — obviously) something went wrong somewhere. Typically it will be an off-by-one error in the grab line or the cursor is off by one. Read the code carefully and you should be able to locate the issue quickly. Either that or take a semi-random guess and see if it passes the test. ;)
import Math;
class ShuffleBag{
var data:Array<Int>;
var cursor:Int;
public function new(){
data=[];
cursor=-1;
}
public function add(item:Int,quantity:Int=1){
for(i in 0...quantity)
data.push(item);
cursor=data.length-1;
}
public function next(){
if(cursor<1){
cursor=data.length-1;
return data[0];
}
var grab:Int=Std.random(cursor+1);
var temp:Int=data[grab];
data[grab]=data[cursor];
data[cursor]=temp;
cursor--;
return temp;
}
}Example usage:
var sb:ShuffleBag=new ShuffleBag(); sb.add(1); //add 1 sb.add(2,3); //add 2 3 times var i:Int=sb.next(); //1 - 25%, 2 - 75%
package{
public class ShuffleBag{
private var data:Array=[];
private var cursor:int;
public function ShuffleBag(){
cursor = -1;
}
public function size():int {
return data.length;
}
public function add(item:int,quantity:int=1):void{
for (var i:int = 0; i < quantity;i++){
data.push(item);
}
cursor=data.length-1;
}
public function next():int{
if(cursor<1){
cursor=data.length-1;
return data[0];
}
var grab:int=Math.floor(Math.random()*(cursor+1));
var temp:int=data[grab];
data[grab]=data[cursor];
data[cursor]=temp;
cursor--;
return temp;
}
}
}Example usage:
var sb:ShuffleBag=new ShuffleBag(); sb.add(1); //add 1 sb.add(2,3); //add 2 3 times var i:int=sb.next(); //1 - 25%, 2 - 75%
function ShuffleBag(){
this.data=[];
this.cursor=-1;
function add(thingy){
if(arguments.length>1){
for(var i=arguments[1];i>0;--i)
this.data.push(thingy);
}else{
this.data.push(thingy);
}
this.cursor=this.data.length-1;
}
function next(){
if(this.cursor<1){
this.cursor=this.data.length-1;
return this.data[0];
}
var grab=Math.floor(Math.random()*(this.cursor+1));
var temp=this.data[grab];
this.data[grab]=this.data[this.cursor];
this.data[this.cursor]=temp;
this.cursor--;
return temp;
}
this.add=add;
this.next=next;
}Example usage:
var sb=new ShuffleBag(); sb.add(1); //add 1 sb.add(2,3); //add 2 3 times var i=sb.next(); //1 - 25%, 2 - 75%
<?php
class ShuffleBag{
private $data=array();
private $cursor=-1;
private $size=0;
public function add($item,$quantity=1){
for($i=0;$i<$quantity;$i++){
$this->data[]=$item;
$this->size++;
}
$this->cursor=$this->size-1;
}
public function next(){
if($this->cursor<1){
$this->cursor=$this->size-1;
return $this->data[0];
}
$grab=rand(0,$this->cursor);
$temp=$this->data[$grab];
$this->data[$grab]=$this->data[$this->cursor];
$this->data[$this->cursor]=$temp;
$this->cursor--;
return $temp;
}
}
?>Example usage:
$sb=new ShuffleBag(); $sb->add(1); //add 1 $sb->add(2,3); //add 2 3 times $i=sb->next(); //1 - 25%, 2 - 75%
#!/usr/bin/perl
package ShuffleBag;
use strict;
my @data;
my $cursor=-1;
sub new{
my($type)=$_[0];
my($self)={};
bless($self,$type);
return($self);
}
sub add{
my($foo,$value,$quantity)=@_;
if(defined($quantity)){
for(my $i=0;$i<$quantity;$i++){
push(@data,$value);
}
}else{
push(@data,$value);
}
$cursor=scalar(@data)-1;
}
sub next{
if($cursor<1){
$cursor=scalar(@data)-1;
return $data[0];
}
my $grab=int(rand($cursor+1));
my $temp=$data[$grab];
$data[$grab]=$data[$cursor];
$data[$cursor]=$temp;
$cursor--;
return $temp;
}Example usage:
my $sb=ShuffleBag; $sb->add(1); #add 1 $sb->add(2); #add 2 3 times my $i=sb->next; #1 - 25%, 2 - 75%
#!/usr/bin/env python
import random
class ShuffleBag:
def __init__(self,seed=None):
self.data=[]
self.cursor=-1
random.seed(seed)
'''add items'''
def add(self, val, quantity=1):
for i in range(quantity):
self.data.append(val)
self.cursor=len(self.data)-1
'''return one item'''
def next(self):
if self.cursor<1:
self.cursor=len(self.data)-1
return self.data[0]
grab=random.randint(0,self.cursor)
temp=self.data[grab]
self.data[grab]=self.data[self.cursor]
self.data[self.cursor]=temp
self.cursor=self.cursor-1
return tempExample usage:
sb=shufflebag.ShuffleBag() sb.add(1) #add 1 sb.add(2,3) #add 2 3 times i=sb.next(); #1 - 25%, 2 - 75%
Comments
Post new comment