Latnam has asked for the wisdom of the Perl Monks concerning the following question:

I'm a bit stuck on a script I am trying to fix. The objective is to find the largest element out of unspecified number range. Currently I have the range set to 10 thru 100, and I want to use 10 in my array size. I check some of the other scripting for this, but none of it made any sense to me as to how I can get this. Here is what I have so far.
#!/usr/bin/perl -w use strict; print "\n"; print "How big is the array: "; chomp (my $n =<STDIN>); print "\n"; print "The array contains: "; print "\n"; my @array; for (my $index=0; $index < $n; $index ++) { push @array, int (rand(91))+10; } foreach (@array) { print $_, "\t"; } print "\n\n"; print "How many elements per line: 4\n"; print "The array contains: "; print "\n"; my $counter = 0; foreach (@array) { print $_, "\t"; $counter ++; if ($counter % 4 == 0) { print "\n"; } } print "\n\n"; print "The largest element is: ";

Replies are listed 'Best First'.
Re: Finding target unspecified value
by ww (Archbishop) on Oct 20, 2013 at 22:20 UTC
    You have numerous good answers above, but here are a few pointers, anyway:
    1. saying things like "I keep getting errors and I don't understand" doesn't help you NOR does it help us to help you. Quote the errors, verbatim; ditto warnings (and learn the difference).
       
    2. Unless this is homework, it seems to me likely that there's no useful purpose to redundant printing of the array NOR any useful end to generating the array with random numbers (between 10 and 100 or any other range). OTOH, if this is homework, level with us in the first place.
       
    3. This may be a 'duh!' on me, but I found I needed multiple readings of your narrative and code to feel confident that I could offer help. I was delighted to return and find you already had sample code... but had this been a busier day, I might well have (figuratively) thrown up my hands and said "If OP can't be clearer (i.e. more precise and un-ambiguous) than that, I can't be bothered to try to help."
       

    Welcome to the Monastery, Latnam; your professed ambition to help others will stand you in good stead.

      This is indeed homework I am struggling with. I am attending a local community college, and I am interested in learning Perl. My professor has been helpful, and suggested to look for outside resources into understanding Perl outside of class. I don't wish to deceive anyone here by my questions, but at times I quite frankly don't understand how the coding works. I apologize for not being upfront with everyone here in the monastery. I will ensure that my questions are indeed clearer, and post what the output message I am reading when inputting coding.
        I am working on the next part of this assignment, and having an issue utilizing an else statement. Using the above coding already in place I inputted this coding
        print "Enter a target value to search for:"; use List::MoreUtils; chomp (my $search = <STDIN>); my $index = List::MoreUtils::first_index {$_ eq $search} @array; if ($search) { print "The last occurence of $search is at index: $index\n"; } else { print "Target is not found\n"; }
        So the code runs, and asks for a target to search for. If its a number displayed, and I enter that number it tells me which index it is. If I enter a number that is not displayed I should see - Target is not found. So for instance the number 100 is not displayed. I see - The last occurrence of 100 is at index -1.
Re: Finding target unspecified value
by boftx (Deacon) on Oct 20, 2013 at 20:06 UTC

    If I understand your question correctly, you wish to find the largest element in an array. This is a fairly common task and the direct approach usually looks something like this:

    use strict; use warnings; # you can initialize this any way you wish, this is proof of concept. my @source = ( 5, 53, 24, 38 ); my $maxseen = 0; my $seen_at = 0; my $cntr = 0; for ( @source ) { if ( $_ > $maxseen ) { $maxseen = $_; $seen_at = $cntr; } ++$cntr; }

    No doubt, this is crude and someone will put up a one-liner using map or grep.

    Update: changed it to have both the max element value and the position at which the max element value was first seen.

    The answer to the question "Can we do this?" is always an emphatic "Yes!" Just give me enough time and money.

      boftx:
      Latnam doesn't generate any negative numbers in his or her  @source array, but if all the numbers were negative, the results would be spurious. List::Util::max and min don't have this problem (although they don't produce any index information; maybe see List::MoreUtils::first_index for this).

      >perl -wMstrict -le "my @source = ( -1, -2, -33, -4 ); ;; my $maxseen = 0; my $seen_at = 0; my $cntr = 0; for ( @source ) { if ( $_ > $maxseen ) { $maxseen = $_; $seen_at = $cntr; } ++$cntr; } ;; print qq{max $maxseen at index $seen_at}; " max 0 at index 0

        Point taken. :)

        The answer to the question "Can we do this?" is always an emphatic "Yes!" Just give me enough time and money.
      How would I utilize what you have posted due to the script I am working with generates random numbers from 10 - 100. There are no set numbers to pick from

        Substitute @array for @source. Of course, Rolf demonstrates a more efficient solution using the max function from List::Util if all you want is the max value and not the location.

        The answer to the question "Can we do this?" is always an emphatic "Yes!" Just give me enough time and money.
Re: Finding target unspecified value
by LanX (Saint) on Oct 20, 2013 at 20:21 UTC
    DB<113> use List::Util qw/max/ DB<114> @array = map {int (rand(91))+10} 1..5 => (36, 56, 42, 38, 49) DB<115> $max = max @array => 56

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      Feeling not a neutered dog...just not getting it. I attempted both version of the code posted, and it keeps popping up errors on my screen. Not even sure anymore what the heck am I doing wrong with this.

        Do this to use my idea:

        ... # add this line my $maxval = 0; foreach (@array) { $maxval = $_ if $_ > $maxval; # and populate as needed here print $_, "\t"; $counter ++; if ($counter % 4 == 0) { print "\n"; } } # then include the value in your final print statement print "The largest element is: $maxval\n";

        On the other hand, to use max as shown by Rolf do this:

        use strict; use List::Utils qw/max/; # add this line ... # rest of your code is unchanged # and then use the function in your final print statement print "The largest element is: " . max(@array) ."\n";
        The answer to the question "Can we do this?" is always an emphatic "Yes!" Just give me enough time and money.
Re: Finding target unspecified value
by Lennotoecom (Pilgrim) on Oct 20, 2013 at 23:01 UTC
    @a = sort map { int(rand(91))+10 } 1..5;
    now
    $a[0] contains the minimum,
    $a[$#a] contains the maximum :)
      @a = sort map { int(rand(91))+10 } 1..5;

      In the absence of a sort comparison block, the default sort ordering is lexicographic-ascending (see Lexicographical order). This ordering produces surprising 'maximum' values — and also 'minimum' values if negative numbers are considered. An explicit numeric-ascending comparison block is needed if  $a[0] and  $a[$#a] are to make sense as numeric min/max values.

      >perl -wMstrict -MData::Dump -le "my @raw = (1, 2, 3, -1, -2, -12, 123, 23); ;; my @sorted_lexical_ascending = sort @raw; dd \@sorted_lexical_ascending; ;; my @sorted_numeric_ascending = sort { $a <=> $b } @raw; dd \@sorted_numeric_ascending; " [-1, -12, -2, 1, 123, 2, 23, 3] [-12, -2, -1, 1, 2, 3, 23, 123]
        I know about $a $b
        the author said "the number between 10 and 100"