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

Hi All wisdom Monks,

I'm new to Perl, so don't know if there is a way to ceil the number of elements inside an array?

I got a task like below:

+Get a list of modules if number of modules is 8 ceiling(6/2)= ceiling(3)=3 -> call the first 3 modules on port 80 and call the last 3 modules on port 8080

+if there is 5 modules deployed -> ceiling(5/2)= ceiling(2.5)=3 -> call the first 3 modules on port 80 and call the last 3 modules on port 8080 (the module “in the middle” will be called twice)

Could you help me with an algorithm or a way to do this in perl?

Replies are listed 'Best First'.
Re: Ceiling elements of an array!
by vinoth.ree (Monsignor) on May 06, 2015 at 08:45 UTC

    The POSIX module (part of the standard perl distribution) implements ceil(), floor(), and a number of other mathematical and trigonometric functions.

    Example,
    use POSIX; $ceil = ceil(3.5);# 4

    All is well. I learn by answering your questions...

      use POSIX;

      POSIX is big and pollutes your namespace with its very many function names.
      This may bite you when you make it a habit to use it just like that.

      Better import exactly what you need: it may pay off to use POSIX qw(ceil floor); # import ceil() and floor()

      Cheers, Sören

      Créateur des bugs mobiles - let loose once, run everywhere.
      (hooked on the Perl Programming language)

      Hi Vinoth.ree,

      Thank for quick answer!

      But how can I apply that method for elements in array?

        how can I apply that method for elements in an array?

        Have a look at pme's answer... or go for loop constructs: foreach for small arrays or while for larger data.

        Cheers, Sören

        Créateur des bugs mobiles - let loose once, run everywhere.
        (hooked on the Perl Programming language)

Re: Ceiling elements of an array!
by hippo (Archbishop) on May 06, 2015 at 09:09 UTC
    don't know if there is a way to ceil the number of elements inside an array?

    There is never any need to ceil the number of elements inside an array because arrays only ever have integral numbers of elements.

    Get a list of modules if number of modules is 8 ceiling(6/2)= ceiling(3)=3

    It is unclear to me where you get that "6" from. Are you sure you have understood the spec?

      Hi Hippo,

      My bad typing the correct number is 6 modules

Re: Ceiling elements of an array!
by pme (Monsignor) on May 06, 2015 at 09:10 UTC
    You can use map to calculate the ceiling of each array element.
    my @a = qw/1.3 5.8 9.5/; my @b = map(ceil($_), @a);
Re: Ceiling elements of an array!
by GotToBTru (Prior) on May 06, 2015 at 15:41 UTC

    I think the problem is confusion over the term 'ceiling'. I believe the desire is to divide n modules into two (nearly) equal groups. If n is odd, obviously, one group will be larger.

    use strict; use warnings; use POSIX qw(ceil); my $modules = shift; my $first_group = ceil($modules/2);0 printf "Call %d on port 80, %d on port 8080\n",$first_group,$modules - + $first_group;
    $: perl divide.pl 8 Call 4 on port 80, 4 on port 8080 $: perl divide.pl 9 Call 5 on port 80, 4 on port 8080 $:

    Vaguely related to Distribute the leftovers.

    Dum Spiro Spero

      Ah, I think you're right -- with that light now on, re-reading the OP it makes perfect sense. I guess my intuition circuit is operating in low-power mode today.

      Curious why you'd go through the effort of loading POSIXjust to get at ceiling()when, in this context, it's always going to be non-negative numbers and the effect can simply be calculated?

      Other than, of course, that the OP did specifically request it . . .

      my $eltcnt = @datary; my $dspcnt = int(($eltcnt + 0.5) / 2);

      Which could likely be reduced to a single, harder-to-read line of code.

        (the module “in the middle” will be called twice)

        Assuming the above is what is wanted (always an even number of calls), another approach (including efforts of others):

        c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -e "my @modules = qw(zero one two three four five six seven); ;; while (@modules) { dd \@modules; my $n = $#modules / 2; print qq{@modules[ 0 .. $n ] -- @modules[ -$n-1 .. -1 ] \n\n}; pop @modules; } " ["zero", "one", "two", "three", "four", "five", "six", "seven"] zero one two three -- four five six seven ["zero", "one", "two", "three", "four", "five", "six"] zero one two three -- three four five six ["zero", "one", "two", "three", "four", "five"] zero one two -- three four five ["zero", "one", "two", "three", "four"] zero one two -- two three four ["zero", "one", "two", "three"] zero one -- two three ["zero", "one", "two"] zero one -- one two ["zero", "one"] zero -- one ["zero"] zero -- zero

        Update: Added '--' marker to output to make partitioning clearer.


        Give a man a fish:  <%-(-(-(-<

        Simpler yet!

        use strict; use warnings; my $modules = shift; my $second_group = int($modules/2); printf "Call %d on port 80, %d on port 8080\n", $modules - $second_group, $second_group;

        Yeah, brain circuits were irrevocably committed to using ceil() in there somewhere, to no real point in a simple case like this.

        Dum Spiro Spero
Re: Ceiling elements of an array!
by marinersk (Priest) on May 06, 2015 at 12:30 UTC

    Maybe I'm missing something here, but it seems these answers are unnecessarily complicated.

    If you want to know how many elements are in an array, Perl gives that to you:

    my $elementCount = @myArray;

    The first three elements are [0], [1], and [2].
    The last three are [-1], [-2], and [-3](counted from the end, so, backwards):

    for (my $currentElementNumber = 0; $currentElementNumber < 3; $cur +rentElementNumber++) { my $currentElementValue = $myArray[$currentElementNumber]; # Do stuff here }

Re: Ceiling elements of an array!
by shadowman13 (Initiate) on May 06, 2015 at 13:15 UTC

    Thanks a lot for all your helps & advice guys!

    Now I got an better point of view to solve this.