Acme-Sort-Bozo
view release on metacpan or search on metacpan
lib/Acme/Sort/Bozo.pm view on Meta::CPAN
package Acme::Sort::Bozo;
use 5.010;
use strict;
use warnings;
use parent qw/Exporter/;
use Carp 'croak';
use List::Util qw/shuffle/;
our @EXPORT = qw/bozo/;
our $VERSION = '0.05';
# bozo()
# Usage:
# Sort a list in standard string comparison order.
#
# my @sorted = bozo( @unsorted );
#
# Sort a list in ascending numerical order:
# sub compare { return $_[0] <=> $_[1] };
# my @sorted = bozo( \&compare, @unsorted );
#
# Warning: Average case is O( n! ).
# Warning: Worst case could approach O(INF).
#
# bozo() is exported automatically upon use.
sub bozo {
my $compare = ref( $_[0] ) =~ /CODE/
? shift
: \&compare;
return @_ if @_ < 2;
my $listref = [ @_ ]; # Get a ref to a copy of @_.
$listref = swap( $listref ) while not is_ordered( $compare, $listref );
return @{ $listref };
}
# Internal use, not exported. Verifies order based on $compare->().
sub is_ordered {
my ( $compare, $listref ) = @_;
ref( $compare ) =~ /CODE/
or croak "is_ordered() expects a coderef as first arg.";
ref( $listref ) =~ /ARRAY/
or croak "is_ordered() expects an arrayref as second arg.";
foreach( 0 .. $#{$listref} - 1 ) {
return 0
if $compare->( $listref->[ $_ ], $listref->[ $_ + 1 ] ) > 0;
}
return 1;
}
# Internal use, not exported. Simply swaps two random elements. The elements
# are guaranteed to be distinct.
sub swap {
my $listref = shift;
my $elements = @{$listref};
my $first = int( rand( $elements ) );
my $second;
do{ $second = int( rand( $elements ) ); } until $second != $first;
# ( $listref->[$first], $listref->[$second] ) = ( $listref->[$second], $listref->[$first] );
( run in 0.904 second using v1.01-cache-2.11-cpan-ad19def0cd9 )