sub maximize_rows { my @array = @_; my %hash = (); foreach (@array) { $hash{$_->[0]}++; $hash{$_->[1]}++; } # the following is done to generate a fitness for each # pair..which happens to be the better fitness of the # elements within the pair push @$_, ($hash{$_->[0]} < $hash{$_->[1]} ? $hash{$_->[1]}:$hash{$_->[0]}) foreach (@array); # sort by fitness @array = sort { $b->[2] <=> $a->[2] } @array; my $counter = 0; foreach my $x (0..$#array - 1) { next unless $array[$x]; foreach my $y ($x+1..$#array) { next unless $array[$y]; %hash = (); $hash{$_}++ foreach (@{$array[$x]}[0,1],@{$array[$y]}[0,1]); if (scalar keys %hash == 4) { $counter++; print "$counter = $array[$x]->[0] $array[$x]->[1] $array[$y]->[0] $array[$y]->[1]$/"; $array[$x] = $array[$y] = undef; last; } } } @array = grep { $_ } @array; print "Unused ",$_ + 1,": $array[$_]->[0] $array[$_]->[1]$/" foreach (0..$#array); } __DATA__ 7 7 1 1 1 2 2 2 2 5 5 5 5 4 4 4 4 4 3 3 3 3 3 8 8 8 8 8 8 6 6 6 6 6 6 6 ==================== 1 = 1 2 2 = 1 3 3 = 1 4 4 = 2 3 5 = 2 4 6 = 2 5 7 = 3 4 8 = 3 5 9 = 3 6 10 = 4 5 11 = 4 6 12 = 5 6 13 = 6 7 14 = 6 8 15 = 7 8 15 counts $VAR1 = { '6' => 2, '8' => 4, '4' => 0, '1' => 0, '3' => 0, '7' => 0, '2' => 0, '5' => 0 }; 1 = 6 8 2 = 4 6 3 = 3 6 4 = 2 6 5 = 5 6 6 = 1 6 7 = 6 7 8 = 4 8 9 = 3 8 10 = 2 8 11 = 5 8 12 = 1 8 13 = 3 4 14 = 2 4 15 = 4 5 16 = 2 3 17 = 3 5 18 = 1 7 18 counts $VAR1 = { '6' => 0, '8' => 0, '4' => 0, '1' => 0, '3' => 0, '7' => 0, '2' => 0, '5' => 0 }; 1 = 1 3 2 4 2 = 1 4 2 3 3 = 3 4 5 6 4 = 3 5 4 6 5 = 3 6 4 5 6 = 6 7 1 2 7 = 6 8 2 5 Unused 1: 7 8 next 1 = 6 8 3 4 2 = 4 6 3 8 3 = 3 6 4 8 4 = 2 6 5 8 5 = 5 6 2 8 6 = 1 6 2 4 7 = 6 7 1 8 8 = 4 5 2 3 9 = 3 5 1 7 #### @array = qw(1 1 1 2 3 4); __DATA__ 1 = 1 2 2 = 1 3 3 = 1 4 3 counts $VAR1 = { '4' => 0, '1' => 0, '3' => 0, '2' => 0 }; 1 = 1 4 2 = 1 3 3 = 1 2 3 counts $VAR1 = { '4' => 0, '1' => 0, '3' => 0, '2' => 0 }; Unused 1: 1 2 Unused 2: 1 3 Unused 3: 1 4 next Unused 1: 1 4 Unused 2: 1 3 Unused 3: 1 2 ... @array = qw(1 2 3 4 4 4); __DATA__ 1 = 1 2 2 = 3 4 2 counts $VAR1 = { '4' => 2, '1' => 0, '3' => 0, '2' => 0 }; 1 = 1 4 2 = 3 4 3 = 2 4 3 counts $VAR1 = { '4' => 0, '1' => 0, '3' => 0, '2' => 0 }; 1 = 1 2 3 4 next Unused 1: 1 4 Unused 2: 3 4 Unused 3: 2 4 #### sub get_pairs { my %hash = (); $hash{$_}++ foreach @_; my @keys = (); @keys = sort { $hash{$b} <=> $hash{$a} } keys %hash; # let's check for condition red if (@keys > 2 && ($hash{$keys[0]} + $hash{$keys[1]} > @keys - 3) && $hash{$keys[3]} == 1) { # !!!!CONDITION RED!!!! # ok...let's calm down...we can do this...just don't panic my $workarea = scalar @keys - 2; if ($keys[1] < int ($workarea / 2)) { $workarea -= 2 * $keys[1]; $hash{$keys[0]} = $keys[1] + int ($workarea / 3); } else { $hash{$keys[0]} = $hash{$keys[1]} = int ($workarea / 2); } } my @pairs = (); foreach my $x (0..$#keys - 1) { next unless $hash{$keys[$x]}; foreach my $y ($x+1..$#keys) { last unless $hash{$keys[$x]}; next unless $hash{$keys[$y]}; push @pairs, ($keys[$x] < $keys[$y] ? [$keys[$x],$keys[$y]]:[$keys[$y],$keys[$x]]); print scalar @pairs," = @{$pairs[$#pairs]}$/"; $hash{$keys[$x]}--; $hash{$keys[$y]}--; } } print scalar @pairs," counts$/"; return @pairs; } __DATA__ 1 1 1 2 3 4 ==================== 1 = 1 2 2 = 1 3 3 = 1 4 3 counts $VAR1 = { '4' => 0, '1' => 0, '3' => 0, '2' => 0 }; 1 = 1 4 2 = 2 3 2 counts $VAR1 = { '4' => 0, '1' => 0, '3' => 0, '2' => 0 }; Unused 1: 1 2 Unused 2: 1 3 Unused 3: 1 4 next 1 = 1 4 2 3