Peter’s blog ✴ Week 310 ✴ 24 February 2025

THE WEEKLY CHALLENGE
Arrays and arrays

The Perl Camel

Task 2

Sort odd even

You are given an array of integers. Write a script to sort odd index elements in decreasing order and even index elements in increasing order in the given array.

Examples


Example 1
Input: @ints = (4, 1, 2, 3)
Output: (2, 3, 4, 1)
Even index elements: 4, 2 => 2, 4 (increasing order)
Odd index elements : 1, 3 => 3, 1 (decreasing order)

Example 2
Input: @ints = (3, 1)
Output: (3, 1)

Example 3
Input: @ints = (5, 3, 2, 1, 4)
Output: (2, 3, 4, 1, 5)
Even index elements: 5, 2, 4 => 2, 4, 5 
   (increasing order)
Odd index elements : 3, 1 => 3, 1 (decreasing order)

Analysis

Three steps are needed:

  • Split the array into sub-arrays of odd and even-indexed values.
  • Sort the even sub-array and reverse sort the odd-indexed one.
  • Merge the two sorted sub-arrays 'like a zip'.

But when would you ever need to do that?

Perl Weekly’s review

from Perl Weekly issue 710

As the title suggests, plenty of loops. Why not? Go for it and don't forget to use DIY tool.

Try it 

Try running the script with any input:



example: 3, 1, 4, 1, 5, 9, 2, 6, 5, 4

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2025-02-24
use utf8;     # Week 310 - task 2 - Sort odd even
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

sort_odd_even(4, 1, 2, 3);
sort_odd_even(3, 1);
sort_odd_even(5, 3, 2, 1, 4);
sort_odd_even(3, 7, 9, 3, 2, 6, 8, 1, 0, 4, 2, 5);
sort_odd_even(-3, -2, -1, 0, 1, 2, 3);

sub sort_odd_even {
    
    my (@array, $v, @odds, @evens, @output);
    
    # separate odds and evens
    @array = @_;
    for $v (0 .. $#array) {
        unshift @odds, $array[$v] if $v & 1;
        unshift @evens, $array[$v] unless $v & 1;
    }
    
    # sort them as specified
    @odds = sort {$b <=> $a} @odds;
    @evens = sort {$a <=> $b} @evens;

    # recreate @array in sorted order
    for $v (0 .. $#array) {
        push @output, shift @odds if $v & 1;
        push @output, shift @evens unless $v & 1;
    }
    
    say qq[\nInput:  \@array = (] . join(', ', @array) . ')';
    say qq[Output:        = (] . join(', ', @output) . ')';
}

13 lines of code

Output from script


Input:  @array = (4, 1, 2, 3)
Output:        = (2, 3, 4, 1)

Input:  @array = (3, 1)
Output:        = (3, 1)

Input:  @array = (5, 3, 2, 1, 4)
Output:        = (2, 3, 4, 1, 5)

Input:  @array = (3, 7, 9, 3, 2, 6, 8, 1, 0, 4, 2, 5)
Output:        = (0, 7, 2, 6, 2, 5, 3, 4, 8, 3, 9, 1)

Input:  @array = (-3, -2, -1, 0, 1, 2, 3)
Output:        = (-3, 2, -1, 0, 1, -2, 3)

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain