perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 355 - Task 2: Mountain Array

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-355/#TASK2
 3 #
 4 # Task 2: Mountain Array
 5 # ======================
 6 #
 7 # You are given an array of integers, @ints.
 8 #
 9 # Write a script to return true if the given array is a valid mountain array.
10 #
11 # An array is mountain if and only if:
12 ## 1) arr.length >= 3
13 ## and
14 ## 2) There exists some i with 0 < i < arr.length - 1 such that:
15 ## arr[0] < arr[1]     < ... < arr[i - 1] < arr[i]
16 ## arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
17 #
18 ## Example 1
19 ##
20 ## Input: @ints = (1, 2, 3, 4, 5)
21 ## Output: false
22 #
23 #
24 ## Example 2
25 ##
26 ## Input: @ints = (0, 2, 4, 6, 4, 2, 0)
27 ## Output: true
28 #
29 #
30 ## Example 3
31 ##
32 ## Input: @ints = (5, 4, 3, 2, 1)
33 ## Output: false
34 #
35 #
36 ## Example 4
37 ##
38 ## Input: @ints = (1, 3, 5, 5, 4, 2)
39 ## Output: false
40 #
41 #
42 ## Example 5
43 ##
44 ## Input: @ints = (1, 3, 2)
45 ## Output: true
46 #
47 ############################################################
48 ##
49 ## discussion
50 ##
51 ############################################################
52 #
53 # First, we check a few necessary cases (>= 3 elements in the array,
54 # first element of the array is smaller than second element). Then,
55 # we walk the array from beginning to end, keeping track of whether
56 # we're still in the ascending phase or already descending. In the
57 # former case we need to bail out if two elements are exactly the same,
58 # in the latter case we need to bail out if the first element is smaller
59 # than the second one. In the end, we just need to exit if we find the
60 # biggest number at the end of the array. In the ascending phase we
61 # also need to check whether two elements are the same and return false
62 # if that's the case. We also need to switch to the descending phase
63 # once a number is smaller than its predecessor in the array while
64 # we're still in the ascending phase.
65 #
66 use v5.36;
67 
68 mountain_array(1, 2, 3, 4, 5);
69 mountain_array(0, 2, 4, 6, 4, 2, 0);
70 mountain_array(5, 4, 3, 2, 1);
71 mountain_array(1, 3, 5, 5, 4, 2);
72 mountain_array(1, 3, 2);
73 
74 sub mountain_array(@ints) {
75     say "Input: (" . join(", ", @ints) . ")";
76     return say "Output: false" unless scalar(@ints) >= 3;
77     return say "Output: false" unless $ints[0] < $ints[1];
78     my $going_up = 1;
79     foreach my $i (1..$#ints-1) {
80         if($going_up) {
81             return say "Output: false" if $ints[$i] == $ints[$i+1];
82             $going_up = 0 if $ints[$i] > $ints[$i+1];
83         } else {
84             return say "Output: false" unless $ints[$i] > $ints[$i+1];
85         }
86     }
87     say "Output: false" if $going_up;
88     say "Output: true";
89 }
90