The weekly challenge 229 - Task 1: Lexicographic Order

 1 #!/usr/bin/perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-229/#TASK1
 3 #
 4 # Task 1: Lexicographic Order
 5 # ===========================
 6 #
 7 # You are given an array of strings.
 8 #
 9 # Write a script to delete element which is not lexicographically sorted (forwards or backwards) and return the count of deletions.
10 #
11 ## Example 1
12 ##
13 ## Input: @str = ("abc", "bce", "cae")
14 ## Output: 1
15 ##
16 ## In the given array "cae" is the only element which is not lexicographically sorted.
17 #
18 ## Example 2
19 ##
20 ## Input: @str = ("yxz", "cba", "mon")
21 ## Output: 2
22 ##
23 ## In the given array "yxz" and "mon" are not lexicographically sorted.
24 #
25 ############################################################
26 ##
27 ## discussion
28 ##
29 ############################################################
30 #
31 # This one is straight foward: increase a counter for each word
32 # in the list that isn't sorted forwards or backwards. For this,
33 # we split the word into its characters, create a new word from the
34 # sorted characters (both forwards and backwards) and if the resulting
35 # word is equal to the original word that one was in lexicographical order.
36 
37 use strict;
38 use warnings;
39 
40 lexicographic_order("abc", "bce", "cae");
41 lexicographic_order("yxz", "cba", "mon");
42 
43 sub lexicographic_order {
44    my @str = @_;
45    print "Input: (" . join(", ", @str) . ")\n";
46    my $count = 0;
47    foreach my $word (@str) {
48       $count++ unless is_ordered($word);
49    }
50    print "Output: $count\n";
51 }
52 
53 sub is_ordered {
54    my $str = shift;
55    my @chars = split //, $str;
56    my $sorted_word = join("", sort(@chars));
57    return 1 if $sorted_word eq $str;
58    $sorted_word = join("", reverse(sort(@chars)));
59    return 1 if $sorted_word eq $str;
60    return 0;
61 }