Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: How can I find the index of the biggest element in an array?

by reisinge (Hermit)
on Mar 14, 2017 at 13:35 UTC ( [id://1184546]=note: print w/replies, xml ) Need Help??


in reply to How can I find the index of the biggest element in an array?

A one-liner where the array elements are the command line arguments:
$ perl -E 'say [ sort { $ARGV[$b] <=> $ARGV[$a] } 0..$#ARGV ]->[0]' 42 + 1000 999 0 -1

Replies are listed 'Best First'.
Re: Answer: How can I find the index of the biggest element in an array?
by reisinge (Hermit) on Mar 14, 2017 at 14:11 UTC

    I was wondering about the efficiency of this solution so I compared it with GrandFather's solution:

    # x.pl use Benchmark qw(timethese cmpthese); cmpthese( -2, { GrandFather => sub { my $idxMax = 0; $ARGV[$idxMax] > $ARGV[$_] or $idxMax = $_ for 1 .. $#ARGV +; $idxMax; }, reisinge => sub { [ sort { $ARGV[$b] <=> $ARGV[$a] } 0..$#ARGV ]->[0]; } } );

    These are the results of the benchmarking:

    $ perl x.pl $(seq 1 1000) Rate reisinge GrandFather reisinge 3742/s -- -3% GrandFather 3864/s 3% -- $ perl x.pl $(seq 1 10000) Rate reisinge GrandFather reisinge 377/s -- -5% GrandFather 395/s 5% -- $ perl x.pl $(seq 1 100000) Rate reisinge GrandFather reisinge 34.1/s -- -18% GrandFather 41.6/s 22% --

    GrandFathers's solution seems to be more efficient, i.e. it's faster (to run) and scales better. But mine is shorter :-).

    It all comes to this: the simplest way to be happy is to do good. -- Helen Keller

      GrandFather's solution may be shorten if a short one-liner is what you're after.

      # reisinge perl -E 'say [ sort { $ARGV[$b] <=> $ARGV[$a] } 0..$#ARGV ]->[0]' 42 1 +000 999 0 -1 # GrandFather perl -E '$m=0; $ARGV[$m] > $ARGV[$_] or $m=$_ for 1..$#ARGV; say $m' 4 +2 1000 999 0 -1 # Shorten, similar performance perl -E '$i=0; ($ARGV[$m] > $_ or $m=$i), $i++ for @ARGV; say $m' 42 1 +000 999 0 -1

      Below, please find a benchmark script for testing against a large list.

      use strict; use warnings; use List::Util 'shuffle'; use Time::HiRes 'time'; # Return index to biggest element. sub reisinge { [ sort { $_[$b] <=> $_[$a] } 0 .. $#_ ]->[0]; } sub GrandFather { my $idxMax = 0; $_[$idxMax] > $_[$_] or $idxMax = $_ for 1 .. $#_; $idxMax; } sub biggest_elm { my ($idxMax,$idx) = (0,0); ($_[$idxMax] > $_ or $idxMax = $idx), $idx++ for @_; $idxMax; } srand 0; my @list = shuffle 1..4e5; for my $code (qw( reisinge GrandFather biggest_elm )) { no strict 'refs'; my ($start, $idx) = (time, $code->(@list)); printf "Index %d, Seconds (%-11s): %0.03f\n", $idx, $code, time - $start; }

      Regards, Mario.

      Edit: Added benchmark script.

        Thanks Mario! Yeah, my solution doesn't scale well at all:

        # Your benchmark script Index 234638, Seconds (reisinge ): 1.919 Index 234638, Seconds (GrandFather): 0.073 Index 234638, Seconds (biggest_elm): 0.072 # Your benchmark script =~ s/1\.\.4e5/1..4e6/; Index 3167631, Seconds (reisinge ): 33.464 Index 3167631, Seconds (GrandFather): 0.876 Index 3167631, Seconds (biggest_elm): 0.775
        As a system administrator, automating the work that needs to be done should be the majority of your job. --PSNA2

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1184546]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2025-06-15 21:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.