#! perl -slw use strict; sub show { my ( $ary, $swaps ) = @_; printf "%2d swaps => %s\n", $swaps, join ' ', @$ary; } sub swapElems { my $t = $_[0][ $_[1] ]; $_[0][ $_[1] ] = $_[0][ $_[2] ]; $_[0][ $_[2] ] = $t; print "[@{$_[0]}] $_[1] <=> $_[2]" } sub do_swaps { my( $ary, $x, $y, $swaps ) = @_; print "do_swaps: $x .. $y"; return $swaps if $y == @$ary; my $saved_y = $y; for( $x .. $y - 1 ) { $y = $saved_y if $y == @$ary; swapElems( $ary, $x++, $y++ ); ++$swaps; } return do_swaps( $ary, $x, $y, $swaps ); } sub swap { my ( $ary, $offset ) = @_; my $swaps = do_swaps( $ary, 0, $offset, 0 ); show( $ary, $swaps ); } #swap( [ qw( a b c 1 2 3 ) ], 3 ); # aref, offset of Y0 #swap( [ qw( a b c d 1 2 ) ], 4 ); #swap( [ qw( a b c d e 1 ) ], 5 ); swap( [ qw( a b c d e f g h i j 1 2 3 4 5 6 7 8 ) ], 10 ); #swap( [ qw( a b c d e f 1 2 3 ) ], 6 ); #### do_swaps: 0 .. 6 [1 b c d e f a 2 3] 0 <=> 6 [1 2 c d e f a b 3] 1 <=> 7 [1 2 3 d e f a b c] 2 <=> 8 [1 2 3 a e f d b c] 3 <=> 6 [1 2 3 a b f d e c] 4 <=> 7 [1 2 3 a b c d e f] 5 <=> 8 do_swaps: 6 .. 9 6 swaps => 1 2 3 a b c d e f #### do_swaps: 0 .. 10 [1]b c d e f g h i j[a]2 3 4 5 6 7] 0 <=> 10 [1[2]c d e f g h i j a[b]3 4 5 6 7] 1 <=> 11 [1 2[3]d e f g h i j a b[c]4 5 6 7] 2 <=> 12 [1 2 3[4]e f g h i j a b c[d]5 6 7] 3 <=> 13 [1 2 3 4[5]f g h i j a b c d[e]6 7] 4 <=> 14 [1 2 3 4 5[6]g h i j a b c d e[f]7] 5 <=> 15 [1 2 3 4 5 6[7]h i j a b c d e f[g] 6 <=> 16 * [1 2 3 4 5 6 7 a[i]j h[b]c d e f g] 7 <=> 10 [1 2 3 4 5 6 7 a b[j]h i[c]d e f g] 8 <=> 11 [1 2 3 4 5 6 7 a b c[h]i j[d]e f g] 9 <=> 12 do_swaps: 10 .. 13 [1 2 3 4 5 6 7 a b c d[i]j h[e]f g] 10 <=> 13 [1 2 3 4 5 6 7 a b c d e[j]h i[f]g] 11 <=> 14 [1 2 3 4 5 6 7 a b c d e f[h]i j[g] 12 <=> 15 do_swaps: 13 .. 16 [1 2 3 4 5 6 7 a b c d e f g[i]j[h] 13 <=> 16 [1 2 3 4 5 6 7 a b c d e f g h[j|i] 14 <=> 16 [1 2 3 4 5 6 7 a b c d e f g h i j] 15 <=> 16 do_swaps: 16 .. 17 16 swaps => 1 2 3 4 5 6 7 a b c d e f g h i j