Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Subroutine Even/Odd

by perlguru22 (Acolyte)
on Oct 04, 2012 at 07:28 UTC ( [id://997196]=perlquestion: print w/replies, xml ) Need Help??

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

Hey,guys I have to create the subroutine that will take the even and odd numbers from an array and print them out but I Haven't been able to combine the 2 into 1 this is what I have

sub even { my @a = @_; foreach $number(@a) { if($number%2==1) { $number = $_; } print "$number"; } print " = Even numbers\n"; } sub odd { my @a = @_; foreach my$number (@a) { if($number%2==0) { $number = $_; } print "$number"; } print "= odd numbers\n"; }
I know there's an easier way to do it but I always complicate my program I would appreciate any help I can get.

Replies are listed 'Best First'.
Re: Subroutine Even/Odd
by tobyink (Canon) on Oct 04, 2012 at 07:36 UTC

    This construct is weird:

    if($number%2==0) { $number = $_; } print "$number";

    It works because $_ is initially undef and you never assign to it. It's incredibly fragile though.

    Here's how I'd do it...

    use 5.010; use List::MoreUtils qw(part); my $numbers = [ 1 .. 10, 211, 1000 ]; my ($evens, $odds) = part { $_ % 2 } @$numbers; say "Even numbers: "; say $_ for @$evens; say "Odd numbers: "; say $_ for @$odds;
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Subroutine Even/Odd
by johngg (Canon) on Oct 04, 2012 at 08:11 UTC

    Another way using push and a ternary.

    $ perl -Mstrict -Mwarnings -E ' > my( @odds, @evens ); > push @{ $_ % 2 ? \ @odds : \ @evens }, $_ for 1 .. 10; > say qq{ Odds: @odds}; > say qq{Evens: @evens};' Odds: 1 3 5 7 9 Evens: 2 4 6 8 10 $

    I hope this is of interest.

    Update: Documentation link corrected, thanks choroba :-)

    Cheers,

    JohnGG

Re: Subroutine Even/Odd
by 2teez (Vicar) on Oct 04, 2012 at 08:16 UTC

    "..I have to create the subroutine that will take the even and odd numbers from an array.."

    A good compact solution has been showed by tobyink.
    However, you might find the following also useful:

    use warnings; use strict; my $numbers = [ 1 .. 10 ]; print even($numbers); ## call even number generator subroutine print $/; print odd($numbers); ## call odd number generator subroutine print $/; ## call combined even and odd number generator subroutine my %even_n_odd_numbers = %{ even_odd($numbers) }; for ( keys %even_n_odd_numbers ) { print $_, " ", join " ", @{ $even_n_odd_numbers{$_} }, $/; } sub even { my ($numbers) = @_; my @even_numbers; for (@$numbers) { push @even_numbers, $_ if $_ % 2 == 0; } return @even_numbers if wantarray; } sub odd { my ($numbers) = @_; my @odd_numbers; for (@$numbers) { push @odd_numbers, $_ if $_ % 2 == 1; } return @odd_numbers if wantarray; } sub even_odd { my ($numbers) = @_; my %even_odd = ( 'even' => undef, 'odd' => undef, ); for (@$numbers) { if ( $_ % 2 == 0 ) { push @{ $even_odd{'even'} }, $_; } else { push @{ $even_odd{'odd'} }, $_; } } return \%even_odd; }
    The combined subroutine is a lot better, because you don't have to repeat codes lines like one did in two different subroutines ( sub even{...} and sub odd{...}) having just only one line that is different from one another.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: Subroutine Even/Odd
by clueless newbie (Curate) on Oct 04, 2012 at 14:32 UTC

    Do not turn the following in unless you're prepared to explain things.

    #!/usr/bin/perl use strict; use warnings; # Effect a "join" with ", " local $"=', ';#" # Use the baby cart so we can call even / odd within quotes to exploit + $" print "@{[even(1,2,3,4)]} are even\n while @{[odd(1,2,3,4)]} are odd\n +"; exit; # Note the use of prototypes so we can pass the list and the desired r +emainder without flattening sub EvenOrOdd (\@$) { my ($numbers,$remainder)=@_; return grep { $_ % 2 == $remainder } @$numbers; }; sub even { EvenOrOdd(@_,0); }; sub odd { EvenOrOdd(@_,1); };
Re: Subroutine Even/Odd
by marquezc329 (Scribe) on Oct 04, 2012 at 18:20 UTC
    Here's what I came up with.
    #!/usr/bin/perl use strict; use warnings; sub num { my $array = shift; my $func = shift; return grep {$_%2==0} @$array if ($func eq 'even'); return grep {$_%2!=0} @$array if ($func eq 'odd'); } my @a = 1..10; my @b = (447..460, 2000..2012); print num(\@a, 'even'), "\n"; print num(\@b, 'odd'), "\n";
    I'm a beginner so please inform me if this is an inefficient/misguided way of accomplishing this.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-03-19 02:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found