in reply to My best attempt at sorting. Kindly suggest improvements/modifications.
Update: Please note that this reply does not consider the OPed algorithm, but instead addresses a general approach to playing with algorithms and algorithm implementations.
Any time you start playing with different algorithms that do the same thing or different implementations of the same algorithm (or, in fact, any new algorithm whatsoever), it's extremely useful to set up a testing framework of some kind. In fact, you might as well get used to setting up the testing framework before you do almost anything else because you'll almost certainly end up doing so sooner or later anyway. (All this assumes you're serious and professional about the work you're doing.) Such a framework allows testing of degenerate, corner/edge, and common cases (update: and exception cases!) easily and quickly. It may be so easy to add new cases that you end up with a huge set of them.
As usual, Perl supports testing with Test::More, Test::Exception and others of that family. I don't say that what follows is ideal, but perhaps food for thought...
use warnings; use strict; use Test::More 'no_plan'; use Test::NoWarnings; use constant TEST_1 => ( # all sorts are numeric-ascending. 'degenerate and boundary test sets', [ [], [] ], [ [0], [0] ], [ [1], [1] ], [ [-1], [-1] ], 'test sets spanning zero', [ [ -11, -13, -9 ], [ -13, -11, -9 ] ], # all < 0 [ [ -11, -13, -9, 2 ], [ -13, -11, -9, 2 ] ], [ [ -11, 3, -9, 2 ], [ -11, -9, 2, 3 ] ], [ [ 11, 3, -9, 2 ], [ -9, 2, 3, 11 ] ], [ [ 11, 3, 9, 2 ], [ 2, 3, 9, 11 ] ], # all > 0 'fancy test set from OP pm#1208073', [ [ -10, 30, 5, 0b1011, 7, 9 ,8, -01111, -10, 1, 3, 9, -30, 5, -100, 0, -1, 0xFF, -3, 30, 0b1011, 3, 2, -300, -0xFF, 15 ], [ -585, -300, -255, -100, -30, -10, -10, -3, -1, 0, 1, 2, 3, 3, 5, 5, 7, 8, 9, 9, 11, 11, 15, 30, 30, 255 ], ], ); note "\n all sorts are numeric-ascending \n\n"; FUNT: # function under test for my $func_name ( qw(built_in_sort sortie_1 sortie_2 comb_sort) ) { note qq{\n=== testing $func_name() ===\n\n}; *test_sort = do { no strict 'refs'; *$func_name; }; VECTOR: # test vector for my $ar_vector (TEST_1) { if (not ref $ar_vector) { note $ar_vector; next VECTOR; } my ($ar_unsorted, $ar_sorted) = @$ar_vector; is_deeply [ test_sort(@$ar_unsorted) ], $ar_sorted; } # end for VECTOR } # end for FUNT done_testing; # functions under test ############################################# # all sorts are numeric-ascending. sub built_in_sort { return sort { $a <=> $b } @_; } sub sortie_1 { my @sorted; my @sortit = @_; my @biglist; my $biggest_so_far = 0; my $smallest_so_far = 0; foreach my $num(@sortit) { if ($num > $biggest_so_far) { $biggest_so_far = $num; } if ($num < $smallest_so_far) { $smallest_so_far = $num; } } @biglist = ($smallest_so_far..$biggest_so_far); foreach my $bignum (@biglist) { foreach my $sortnum (@sortit) { if ($bignum == $sortnum) { push @sorted, $bignum; } } } return @sorted; } sub sortie_2 { my ($biggest, $smallest) = (0, 0); for my $n (@_) { $biggest = $n if $biggest < $n; $smallest = $n if $smallest > $n; } my %n_seen; ++$n_seen{$_} for @_; return map { $n_seen{$_} ? ($_) x $n_seen{$_} : () } $smallest .. $biggest ; } sub comb_sort { # from Laurent_R pm#1208002 my $ar = [ @_ ]; my $max = @$ar; my $gap = $max; COMB_PASS: while (1) { my $swapped = 0; $gap = int ($gap / 1.3); $gap = 1 if $gap < 1; my $lmax = $max - $gap - 1; SWAP_TEST: foreach my $i (0..$lmax) { my $j = $i + $gap; next SWAP_TEST if $ar->[$i] <= $ar->[$j]; # no swap (@{ $ar }[$i, $j], $swapped) = (@{ $ar }[$j, $i], 1); } last COMB_PASS if $gap == 1 and $swapped == 0; } return @$ar; }
Give a man a fish: <%-{-{-{-<
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: My best attempt at sorting. Kindly suggest improvements/modifications.
by pritesh (Scribe) on Jan 30, 2018 at 20:44 UTC |