Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
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 cooling their heels in the Monastery: (5)
As of 2024-04-24 11:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found