use Algorithm::Networksort ':all'; my $inputs = $ARGV[0] || 5; my $n_comparators = $ARGV[1] || $inputs * 2; my @network = ([0,1]) x $n_comparators; my $combinations = (($inputs * ($inputs - 1))/2)**$n_comparators; my $start_at = $ARGV[2] || 0; print "N = $inputs, searching for a sort using $n_comparators comparators.\nNumber of possible combinations: $combinations\n\n"; for (my $j = 0; $j < $start_at; $j++) { @network = next_network(\@network, $inputs, $n_comparators); } for (my $j = $start_at; $j < $combinations; $j++) { print STDERR sprintf("%08d: ", $j), nw_format(\@network), "\n" if (($j % 1000) == 0); @network = next_network(\@network, $inputs, $n_comparators); if (zero_one(\@network, $inputs) == 0) { print "Solved! at $j of $combinations.\n"; last; } } my @grouped_network = nw_group(\@network, $inputs); foreach my $group (@grouped_network) { print nw_format($group), "\n"; } print nw_graph(\@network, $inputs); exit(0); sub comp_incr { my($from, $to, $inputs) = @_; $to++; if ($to == $inputs) { $from++; return (0,1) if ($from == $inputs - 1); return ($from, $from+1); } return ($from, $to); } sub next_network { my $network_ref = shift; my $inputs = shift; my $n_comps = shift; for (my $j = $n_comps - 1; $j >= 0; $j--) { my $comparator = $$network_ref[$j]; my($from, $to) = comp_incr(@$comparator, $inputs); $$network_ref[$j] = [$from, $to]; return @$network_ref unless ($from == 0 && $to == 1); } return @$network_ref; } sub zero_one { my $network_ref = shift; my $inputs = shift; my $error; foreach my $x (1 .. (1 << $inputs) - 2) { my @bitlist = (split(//, unpack("B32", pack("N", $x))))[32 - $inputs .. 31]; my $x_binary = join "", @bitlist; nw_sort($network_ref, \@bitlist); $sort_string = join "", @bitlist; if ($sort_string !~ qr/^0+1+$/) { # $error = "Failed to sort at $x [0b$x_binary]. Returned '$sort_string' instead."; return $x; } } return 0; }