Моя реализация в Perl с использованием простого взвешивания.
use Modern::Perl;
my @data;
{
use List::MoreUtils qw'natatime';
my $iter = natatime 2, qw'
X1 0
X2 1
X3 0
X4 1
X5 0
';
while( my($a,$b) = $iter->() ){
push @data, [$a,$b]
}
}
my @sorted = sort {
($a->[1] <=> $b->[1]) * -2 + # gives more weight to second element
($a->[0] cmp $b->[0])
} @data;
say "Name\tDept\n";
say join "\t", @$_ for @sorted;
Name Dept
X2 1
X4 1
X1 0
X3 0
X5 0
Результатом сравнения <=>
и cmp
является значение -1,0,1
.
Умножив один из кампарионов на два, мы получим одно из -2,0,2
.
После добавления значения другого оператора мы получаем один из -3,-2,-1,0,1,2,3
Я хотел посмотреть, сколько сравнений будет сделано, поэтому добавил некоторую отладочную информацию и придумал это.
a b a1 b1 a0 b0
X1,0 -> X2,1 0 --> 1 X1 <- X2
X3,0 -> X4,1 0 --> 1 X3 <- X4
X2,1 <- X4,1 1 - 1 X2 <- X4
X4,1 <- X1,0 1 <-- 0 X4 -> X1
X1,0 <- X3,0 0 - 0 X1 <- X3
X2,1 <<- X5,0 1 <-- 0 X2 <- X5
X5,0 ->> X4,1 0 --> 1 X5 -> X4
X5,0 -> X1,0 0 - 0 X5 -> X1
X5,0 -> X3,0 0 - 0 X5 -> X3
The arrows point at the earlier value.