Peter
Peter Campbell Smith

Count the unsorted
and two thirds is enough

Weekly challenge 229 — 7 August 2023

Week 229 - 7 Aug 2023

Task 1

Task — Lexicographically ordered

You are given an array of strings.

Write a script to delete any element which is not lexicographically sorted (forwards or backwards) and return the count of deletions.

Examples


Example 1
Input: @str = ("abc", "bce", "cae")
Output: 1
In the given array "cae" is the only element which is not lexicographically sorted.

Example 2
Input: @str = ("yxz", "cba", "mon")
Output: 2
In the given array "yxz" and "mon" are not lexicographically sorted.

Analysis

The key to this task is to identify the unordered strings. I chose to do that by sorting the characters of each string both forwards and backwards, and comparing those to the original string. If neither match, then the string is marked for deletion.

The task asks us to delete the offending strings from the list, but as the output required is simply a count, possibly with a list, of the unordered strings, it seems unnecessary to actually delete them, and instead I just accumulated a list of the unmatching ones.

Try it 

Example: one, two, three, four, five

Script


#!/usr/bin/perl

use v5.16;    # The Weekly Challenge - 2023-08-07
use utf8;     # Week 229 task 1 - Lexicographic order
use strict;   # Peter Campbell Smith
use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

lexicographic_order('abc', 'bce', 'cae');
lexicographic_order('yxz', 'cba', 'mon');
lexicographic_order('abc', 'def', 'xyz');
lexicographic_order('zyx', 'wus', 'cba');
lexicographic_order(qw(now is the time for all good men to come to the aid of the party));

sub lexicographic_order {
    
    my (@bad, $string);
    
    # find any strings that don't change if sorted lexicographically
    for $string (@_) {
        push(@bad, $string) 
            if ($string ne join('', sort(split('', $string)))
            and $string ne join('', reverse sort(split('', $string))));
    }
    
    # show results
    say qq[\nInput:  \@str = (']. join(qq[', '], @_) . qq[')];
    say qq[Output: ] . (scalar @bad);
    say qq[   Disordered: ('] . join (qq[', '], @bad) . qq[')] if @bad;
}

Output


Input:  @str = ('abc', 'bce', 'cae')
Output: 1
   Disordered: ('cae')

Input:  @str = ('yxz', 'cba', 'mon')
Output: 2
   Disordered: ('yxz', 'mon')

Input:  @str = ('abc', 'def', 'xyz')
Output: 0

Input:  @str = ('zyx', 'wus', 'cba')
Output: 0

Input:  @str = ('now', 'is', 'the', 'time', 'for', 'all', 'good', 'men', 'to', 'come', 'to', 'the', 'aid', 'of', 'the', 'party')
Output: 6
   Disordered: ('time', 'good', 'men', 'come', 'aid', 'party')