Checking the Ascendency/Descendency of Numeric Array of Any Size

by monkfan (Curate)
 on Mar 23, 2007 at 08:06 UTC Need Help??
monkfan has asked for the wisdom of the Perl Monks concerning the following question:

Is there an efficient and compact way to do it?
For example, given the array of any size:

Example 1:
my @arr1 = (15, 2, 7); #return 0
Example 2:
my @arr2 = (1, 2, 3, 4, 20, 100); #return 1
Example 3:
my @arr3 = (2, 3, 5, 7, 2); #return 0

Regards,
Edward

Replies are listed 'Best First'.
Re: Checking the Ascendency/Descendency of Numeric Array of Any Size
by BrowserUk (Pope) on Mar 23, 2007 at 11:33 UTC
Creative solution!

However it would fail for a list containing an element with value zero since in that case the shift operation returns a false result.
This should fix it:

sub isAscending2{ \$_[0] < \$_[1] and (shift() or 1) or return 0 while @_>1; return 1; }
Re: Checking the Ascendency/Descendency of Numeric Array of Any Size
by dk (Chaplain) on Mar 23, 2007 at 08:46 UTC
I like List::Util, so for example:
use List::Util qw(reduce); sub is_asc { reduce { (defined(\$a) and \$a < \$b) ? \$b : undef } @_ } print is_asc(1,2,3,4) ? 1 : 0, "\n"; print is_asc(1,3,2,4) ? 1 : 0, "\n"; 1 0
But then is_asc(-2,-1,0) comes out false.
0 is false, undef is also false, but 0 is not undef. is_asc(-2,-1,0) returns 0, not undef.
Re: Checking the Ascendency/Descendency of Numeric Array of Any Size
by roboticus (Chancellor) on Mar 23, 2007 at 12:10 UTC
monkfan:

Here's a snippet of code that will check the monotonicity of a series and return the direction, too. If you only want 0/1, you can simply wrap the final return value with abs(...).

#!/usr/bin/perl -w use strict; use warnings; sub check_monotonicity { # Return 0 if series is non-monotonic, +1 if it's # an increasing series, -1 if it decreases. my \$dir = shift; \$dir = shift if ! \$dir; return 0 if ! \$dir; my \$next = shift; return 0 if ! (\$next - \$dir); my \$sign = (\$next - \$dir) / abs(\$next - \$dir); \$dir = \$next; while (\$next = shift) { return 0 unless (\$next - \$dir) * \$sign > 0; \$dir = \$next; } return \$sign; } my @a = (0, 0, 0); print check_monotonicity(@a), ": ", join(', ',@a), "\n"; @a = (0, 2, 4, 6, 8); print check_monotonicity(@a),": ", join(', ',@a), "\n"; @a = (1, 3, 5, 7, 9, 11); print check_monotonicity(@a),": ", join(', ',@a), "\n"; @a = (10, 9, 8, 7, 6, 5); print check_monotonicity(@a),": ", join(', ',@a), "\n"; @a = (5, 3, 1, -1, -3, -5); print check_monotonicity(@a), ": ", join(', ',@a), "\n"; @a = (1, 2, 3, 3, 4); print check_monotonicity(@a), ": ", join(', ',@a), "\n";
This code produces:
root@swill ~/PerlMonks \$ ./AscDesc.pl 0: 0, 0, 0 1: 0, 2, 4, 6, 8 1: 1, 3, 5, 7, 9, 11 -1: 10, 9, 8, 7, 6, 5 -1: 5, 3, 1, -1, -3, -5 0: 1, 2, 3, 3, 4 root@swill ~/PerlMonks \$
--roboticus
Re: Checking the Ascendency/Descendency of Numeric Array of Any Size
by Anno (Deacon) on Mar 23, 2007 at 17:39 UTC
sub is_asc { ( undef, my @lagged) = @_; \$_ >= shift or return 0 for @lagged; return 1; }
Anno
Re: Checking the Ascendency/Descendency of Numeric Array of Any Size
by odrm (Novice) on Mar 23, 2007 at 14:28 UTC
sub is_ascending { \$_ != shift and return for sort {\$a <=> \$b} @_; 1; }

Create A New User
Node Status?
node history
Node Type: perlquestion [id://606183]
Approved by graq
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (10)
As of 2018-05-23 13:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
World peace can best be achieved by:

Results (168 votes). Check out past polls.

Notices?