sub mix { my $bag = shift; my @str = sort { $bag->{$a} <=> $bag->{$b} } keys %$bag; my $list = ""; while( @str ) { my $tbi = shift @str; my $count = $bag->{$tbi}; $tbi .= shift @str while( @str and $bag->{$str[0]} == $count ); my $l = length $list; if( !$l ) { $list = $tbi x $count; } else { for my $pos ( reverse 0..$count-1 ) { substr( $list, round($pos / ($count-1) * $l), 0 ) = $tbi ; } } } my @series = split '', $list; return \@series; } sub gen { # kennethk my $href = shift; my %score = %$href; my $norm = sum values %score; my @series; for (1 .. $norm) { my ($max, $elem) = 0; for (keys %score) { ($max, $elem) = ($score{$_}, $_) if $score{$_} >= $max; $score{$_} += $href->{$_}; } push @series, $elem; $score{$elem} -= $norm; } return \@series; } sub genUK { # BrowserUK my $href = shift; my @kByV = sort{ $href->{ $b } <=> $href->{ $a } } keys %$href; my @dist = ( $kByV[0] ) x $href->{ $kByV[0] }; shift @kByV; while( @kByV ) { my $k = shift @kByV; my $v = $href->{ $k }; my $n = int( @dist / ( $v+1 ) ); my $p = $n * $v; splice( @dist, $p, 0, $k ), $p -= $n for reverse 1 .. $v; } return \@dist; } sub kcott { my $bagref = shift; my %bag = %$bagref; my @distribution; for my $key (sort { $bag{$b} <=> $bag{$a} } keys %bag) { my $base_offset = int(@distribution / ($bag{$key} + 1) + 0.5); my $offset = $base_offset; for (1 .. $bag{$key}) { next unless $_ % 2; splice @distribution, $offset, 0, $key; if ($_ < $bag{$key}) { splice @distribution, -$offset, 0, $key; } $offset += $base_offset + 1; } } return \@distribution; }