#!/usr/local/bin/perl # $Id: heapsort.perl,v 1.11 2001/05/08 02:46:59 doug Exp $ # http://www.bagley.org/~doug/shootout/ # Matt Harris suggested passing the array via typeglob use strict; use constant IM => 139968; use constant IA => 3877; use constant IC => 29573; use vars qw(@ra); my $LAST = 42; sub gen_random { ($_[0] * ($LAST = ($LAST * IA + IC) % IM)) / IM } sub heapsort ($\@) { my $n = shift; # use typeglob ra to refer to array. local *ra = shift; my($rra, $i, $j); my $l = ($n >> 1) + 1; my $ir = $n; while (1) { if ($l > 1) { $rra = $ra[--$l]; } else { $rra = $ra[$ir]; # print('ir=1 ', $ir, ' <- ', 1, ' (', sprintf("%.10g", $ra[1]), ')', "\n" ); $ra[$ir] = $ra[1]; if (--$ir == 1) { # print('1=rra ', 1, ' <- ', sprintf("%.10g", $rra), "\n" ); $ra[1] = $rra; return; } } $i = $l; $j = $l << 1; # print " l=$l i=$i j=$j ir=$ir\n"; while ($j <= $ir) { $j++ if (($j < $ir) && ($ra[$j] < $ra[$j+1])); # print(" in2while, j=$j rra=", sprintf("%.10g", $rra), ' ra(j)=', sprintf("%.10g", $ra[$j]), "\n"); if ($rra < $ra[$j]) { # print('i=j ', $i, ' <- ', $j, ' (', sprintf("%.10g", $ra[$j]), ')', "\n" ); $ra[$i] = $ra[$j]; $j += ($i = $j); } else { $j = $ir + 1; } } # print('i=rra ', $i, ' <- ', sprintf("%.10g", $rra), "\n" ); $ra[$i] = $rra; } } my $N = $ARGV[0]; $N = 1 if ($N < 1); # create an array of N random doubles my @ary = (); for (my $i=1; $i<=$N; $i++) { $ary[$i] = gen_random(1.0); } heapsort($N, @ary); printf("%.10g\n", $ary[-1]);