my %dist_0_00; # for exact matches my %dist_0_05; # for points that may match within 0.05 my %dist_0_50; # for points that may match within 0.50 my %dist_5_00; # for points that may match within 5.00 my ($y005,$y050,$y500); for $y (@y_set) { $y005 = floor($y*10)/10; $y050 = floor($y); $y500 = floor($y/10)*10; $dist_0_00{$y}=[$y]; push @{$dist_0_05{$y005}}, $y; push @{$dist_0_05{$y005+0.1}}, $y; push @{$dist_0_50{$y050}}, $y; push @{$dist_0_50{$y050+1.0}}, $y; push @{$dist_5_00{$y500}}, $y; push @{$dist_5_00{$y500+10.0}},$y; } # so if $x = 18.94, all the matches that are within 0.05 # of it are in either in the array at arrayref # $dist_0_05{18.8} or in the one at $dist_0_05{18.9} # similarly, the matches within 0.5 are in two hash elements # of %dist_0_50. my @matches; my $x_bin; for $x ($x_set) { if ( $dist_0_00{$x} ) { # exact match push @match,[$x,$x]; next; } $x_bin = floor(($x-0.05)*10).10.0; if ( @y_test_low = $dist_0_05{$xbin} || @y_test_high= $dist_0_05{$xbin+0.1} ) { if (defined($y=have_best_within(0.05,@y_test_low,@y_test_high)){ push @match,[$x,$]; next; } } # similarly for 0.5 and 5.0 thresholds } # for $x