Peter
Peter Campbell Smith

Gnirsts and nothing left

Weekly challenge 226 — 17 July 2023

Week 226 - 17 Jul 2023

Task 1

Task — Shuffle strings

You are given a string and an array of indices of the same length as string. Write a script to return the string after re-arranging the characters in the correct order.

Examples


Example 1
Input: $string = 'lacelengh', @indices = (3,2,0,5,4,8,6,7,1)
Output: 'challenge'

Example 2
Input: $string = 'rulepark', @indices = (4,7,3,1,0,5,2,6)
Output: 'perlraku'

Analysis

Analysis of the examples reveals that the essence of this challenge is:

jumbled_text[j] == plain_text[indices[j]]

... which pretty well reduces to a one-liner. The only quirk is that the plain_text string needs to be initialised to a string of '_' characters the same length as the jumbled text, because it will not be populated left to right.

Note also the use of substr() as an lvalue, allowing a single character in the middle of the string to be substituted.

Try it 

String - eg: rulepark

Indices - eg: 4, 7, 3, 1, 0, 5, 2, 6

Script


#!/usr/bin/perl

use v5.16;    # The Weekly Challenge - 2023-07-17
use utf8;     # Week 226 task 1 - Shuffle string
use strict;   # Peter Campbell Smith
use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

shuffle_string('lacelengh', [3, 2, 0, 5, 4, 8, 6, 7, 1]);
shuffle_string('rulepark', [4, 7, 3, 1, 0, 5, 2, 6]);
shuffle_string('aaacccdeefgiiiiiiillloopprrssstuux',
    [6, 11, 24, 5, 19, 29, 27, 3, 20, 9, 12, 8, 13, 15, 18, 23, 26, 30, 
    7, 14, 25, 28, 31, 2, 22, 4, 10, 0, 16, 33, 17, 1, 32, 21]);
    
sub shuffle_string {
    
    my ($string, @indices, $result);
    
    # initialise
    $string = $_[0];
    @indices = @{$_[1]};
    
    # prepopulate $result with '_'
    $result = '_' x length($string);
    
    # copy chars: string[j] -> result[indices[j]]
    substr($result, $indices[$_], 1) = substr($string, $_, 1) for 0 .. @indices - 1;

    say qq[\nInput:  \$string = '$string',\n        \@indices = (] . join(qq[, ], @indices) . qq[)];
    say qq[Output: '$result'];
}

Output


Input:  $string = 'lacelengh',
        @indices = (3, 2, 0, 5, 4, 8, 6, 7, 1)
Output: 'challenge'

Input:  $string = 'rulepark',
        @indices = (4, 7, 3, 1, 0, 5, 2, 6)
Output: 'perlraku'

Input:  $string = 'aaacccdeefgiiiiiiillloopprrssstuux',
        @indices = (6, 11, 24, 5, 19, 29, 27, 3, 20, 9, 12, 8, 13, 15, 18, 23, 26, 30, 7, 14, 25, 28, 31, 2, 22, 4, 10, 0, 16, 33, 17, 1, 32, 21)
Output: 'supercalifragilisticexpialidocious'