Peter’s blog ✴ Week 279 ✴ 22 July 2024

THE WEEKLY CHALLENGE
Scrambled and split

The Perl Camel

Task 1

Sort letters

You are given two arrays, @letters and @weights. Write a script to sort the given array @letters based on the @weights.

Examples


Example 1
Input: @letters = ('R', 'E', 'P', 'L')
       @weights = (3, 2, 1, 4)
Output: PERL

Example 2
Input: @letters = ('A', 'U', 'R', 'K')
       @weights = (2, 4, 1, 3)
Output: RAKU

Example 3
Input: @letters = ('O', 'H', 'Y', 'N', 'P', 'T')
       @weights = (5, 4, 2, 6, 1, 3)
Output: PYTHON

Analysis

Inspection of the examples reveals that:

sorted[weights[j]] = letters[j]

And allowing for Perl's zero-based arrays that is exactly my solution.

I could have made it strictly one line by using @_ directly rather than copying the arguments of the subroutine into local arrays, but

$sorted[$_[1]->[$_] - 1] = $_[0]->[$_] 
   for 0 .. @{$_[0]} - 1;

is not very easy to read (but it does work).

Perl Weekly’s review

from Perl Weekly issue 679

Nice hack to get split string task with nice explanation. Well done.

Try it 

Try running the script with any input:



example: e, h, o, l, l



example: 2, 1, 5, 4, 3

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-07-22
use utf8;     # Week 279 - task 1 - Sort letters
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

sort_letters(['R', 'E', 'P', 'L'], [3, 2, 1, 4]);
sort_letters(['A', 'U', 'R', 'K'], [2, 4, 1, 3]);
sort_letters(['a', 'C', 'e', 'e', 'g', 'h', 'l', 'l', 'n'], [3, 1, 6, 9, 8, 2, 4, 5, 7]);

sub sort_letters {
    
    my (@letters, @weights, @sorted);
    
    @letters = @{$_[0]};
    @weights = @{$_[1]};

    # rearrange the letters
    $sorted[$weights[$_] - 1] = $letters[$_] for 0 .. @letters - 1;

    printf(qq[\nInput:  \@letters = ('%s'), \@weights = (%s)\n], join(qq[', '], @letters), join(', ', @weights));
    printf(qq[Output: %s\n], join('', @sorted));
}

7 lines of code

Output from script


Input:  @letters = ('R', 'E', 'P', 'L'), 
        @weights = (3, 2, 1, 4)
Output: PERL

Input:  @letters = ('A', 'U', 'R', 'K'), 
        @weights = (2, 4, 1, 3)
Output: RAKU

Input:  @letters = ('a', 'C', 'e', 'e', 'g', 'h', 'l', 
        'l', 'n'), @weights = (3, 1, 6, 9, 8, 2, 4, 5, 7)
Output: Challenge

 

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