1 #!/usr/bin/perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-204/#TASK1
 3 # Task 1: Monotonic Array
 4 #
 5 # You are given an array of integers.
 6 #
 7 # Write a script to find out if the given array is Monotonic. Print 1 if it is otherwise 0.
 8 #
 9 ## An array is Monotonic if it is either monotone increasing or decreasing.
10 #
11 ## Monotone increasing: for i <= j , nums[i] <= nums[j]
12 ## Monotone decreasing: for i <= j , nums[i] >= nums[j]
13 #
14 #
15 ## Example 1
16 ##
17 ## Input: @nums = (1,2,2,3)
18 ## Output: 1
19 #
20 ## Example 2
21 ##
22 ## Input: @nums (1,3,2)
23 ## Output: 0
24 #
25 ## Example 3
26 ##
27 ## Input: @nums = (6,5,5,4)
28 ## Output: 1
29 #
30 ############################################################
31 ##
32 ## discussion
33 ##
34 ############################################################
35 #
36 # While walking the array we have to check in each step if
37 # we're still monotone. In order to achieve this we need to
38 # know if we're monotone increasing or monotone decreasing
39 # so far (or still constant, in which case both are still
40 # possible). If we were increasing and switch to decreasing
41 # or vice versa the whole array is not monotone and we can
42 # return 0 right away. If we reach the end of the array
43 # without any such switch we are monotone and can return 1.
44 
45 use strict;
46 use warnings;
47 
48 my @examples = (
49    [1, 2, 2, 3],
50    [1, 3, 2],
51    [6, 5, 5, 4]
52 );
53 
54 foreach my $nums (@examples) {
55    print "Input: (" . join(", ", @$nums) . ")\n";
56    print "Output: " . is_monotone(@$nums) . "\n";
57 }
58 
59 # given an array, return 1 if it is monotone and 0 otherwise
60 sub is_monotone {
61    # put the first element of the array into $last, the rest into @nums
62    my ($last, @nums) = @_;
63    my $direction = 0; # so far we're neither increasing nor decreasing
64    foreach my $elem (@nums) {
65       if($direction > 0) { # we're monotone increasing so far
66          if($elem < $last) {
67             # we're no longer monotone
68             return 0;
69          }
70       } elsif ($direction < 0) { # we're monotone decreasing so far
71          if($elem > $last) {
72             # we're no longer monotone
73             return 0;
74          }
75       } else { # still constant, we can still be increasing or decreasing
76          if($elem > $last) {
77             $direction = 1; # now we know we're increasing
78          } elsif ($elem < $last) {
79             $direction = -1; # now we know we're decreasing
80          }
81       }
82       # make sure we have $last set to the previous element in the next step
83       $last = $elem;
84    }
85    return 1;
86 }