Circle Sort
The given algorithm can be simplified in several ways. There's no need to compute the midpoint, since the hi/lo will end up there. The extra swap conditional can be eliminated by incrementing hi at the correct moment inside the loop. There's no need to pass accumulated swaps down the call stack.
This does generic comparisons, so it works on any ordered type, including numbers or strings.
sub circlesort (@x, $beg, $end) {
my $swaps = 0;
if $beg < $end {
my ($lo, $hi) = $beg, $end;
repeat {
if @x[$lo] after @x[$hi] {
@x[$lo,$hi] .= reverse;
++$swaps;
}
++$hi if --$hi == ++$lo
} while $lo < $hi;
$swaps += circlesort(@x, $beg, $hi);
$swaps += circlesort(@x, $lo, $end);
}
$swaps;
}
say my @x = (-100..100).roll(20);
say @x while circlesort(@x, 0, @x.end);
say @x = <The quick brown fox jumps over the lazy dog.>;
say @x while circlesort(@x, 0, @x.end);Output:
Last updated
Was this helpful?