ur @set; our $max_reps; our $len; sub gen_almut { my $result = ''; while (length($result) < $len) { my $char = $set[ rand @set ]; next if substr($result, -$max_reps) eq $char x $max_reps; $result .= $char; } $result; } sub gen_almut_mod2 { my $result = ''; for (1..$len) { my $char = $set[ rand @set ]; redo if substr($result, -$max_reps) eq $char x $max_reps; $result .= $char; } $result; } sub gen_almut_mod3 { my $result = ''; my $char; for (1..$len) { do { $char = $set[ rand @set ] } while substr($result, -$max_reps) eq $char x $max_reps; $result .= $char; } $result; } sub gen_almut_mod4 { my $result = ''; while (length($result) < $len) { my $char = $set[ rand @set ]; $result .= $char if substr($result, -$max_reps) ne $char x $max_reps; } $result; } my $buf; sub gen_salva2 { while (length $buf < $len) { $buf .= $set[rand @set] for (1..$len*100); $buf =~ s/(.)\1{$max_reps,}/$1 x $max_reps/ge; } substr($buf, -$len, $len, ''); } sub gen_salva { my $out = ''; my $last_ix = -1; my $reps = 0; for (1..$len) { my $ix; if ($reps >= $max_reps) { $ix = int rand(@set - 1); $ix++ if $ix >= $last_ix; } else { $ix = int rand(@set); } if ($ix == $last_ix) { $reps++; } else { $last_ix = $ix; $reps = 1; } $out .= $set[$ix]; } $out; } use Benchmark qw(cmpthese); $len = 12; for my $elements (2, 5, 10) { @set = (1..$elements); for $max_reps (1, 2, 3) { print "elements: $elements max_reps: $max_reps\n"; $buf = ''; cmpthese(-4, { almut => \&gen_almut, almut_mod2 => \&gen_almut_mod2, almut_mod3 => \&gen_almut_mod3, almut_mod4 => \&gen_almut_mod4, salva2 => \&gen_salva2, salva => \&gen_salva } ); } }