Проблем даже несколько.
Главная -- в grep'ах потерялись отрицания, и получается, что ищем элементы массива, у которых и первая, и вторая половинки равны одновременно и первой, и второй половинке эталонного (случайного) элемента. Таких никогда не находится.
Вторая серьезная проблема: в функции adsp создается ссылка на анонимный массив ($arrset), который не возвращается из функции. Исходный же массив @arrset не модифицируется.
Далее: rand возвращает вещественные числа, использовать их для доступа по индексу в массиве -- странновато (хотя и работает -- вещественные округляются).
И наконец: ни одна переменная в фунции adsp не объявлена (my var), а значит, и use strict в скрипте не используется, т.е. perl не следит за тем, чтобы не использовались необъявленные переменные. В таких случаях обязательно появляются ошибки "присвоили одной переменной, а использовать пытаемся другую".
Итого. По-моему, код должен был быть таким:
sub adsp {
my $rand = int rand @arrset;
my $rand_num = $arrset[$rand];
$rand_num =~ /^(\d+)_(\d+)$/;
my $buf = $1;
my $buf2 = $2;
@arrset = grep { !/^\d+_$buf$/ } @arrset;
@arrset = grep { !/^\d+_$buf2$/ } @arrset;
@arrset = grep { !/^${buf}_\d+$/ } @arrset;
@arrset = grep { !/^${buf2}_\d+$/ } @arrset;
return $rand_num;
}
Случайные индекс берется целый, модифицируется исходный массив @arrset, в grep'ах условия с отрицанием, все переменные объявлены лексическими (my).
И обязательно используйте в каждом скрипте
use strict;
use warnings;
-- это экономит много времени на отладке.