Perl Weekly Challenge 264.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 264.

Task 1: Greatest English Letter

Submitted by: Mohammad Sajid Anwar
You are given a string, $str, made up of only alphabetic characters [a..zA..Z].

Write a script to return the greatest english letter in the given string.

A letter is greatest if it occurs as lower and upper case. Also letter ‘b’ is greater
than ‘a’ if ‘b’ appears after ‘a’ in the English alphabet.

Example 1
Input: $str = 'PeRlwEeKLy'
Output: L

There are two letters E and L that appears as lower and upper.
The letter L appears after E, so the L is the greatest english letter.
Example 2
Input: $str = 'ChaLlenge'
Output: L
Example 3
Input: $str = 'The'
Output: ''

First I count the times each letter appears. Then I grep those letters that appear in both upper and lower case and I choose the maximum with maxstr from List::Utils. The code fits a one-liner.

Example 1:

perl -MList::Util=maxstr -E '
$s{$_}++ for split "", $i=shift; say "$i -> ",  maxstr grep {$_ eq uc && $s{lc $_}}keys %s;
' PeRlwEeKLy

Results:

PeRlwEeKLy -> L

Example 2:

perl -MList::Util=maxstr -E '
$s{$_}++ for split "", $i=shift; say "$i -> ",  maxstr grep {$_ eq uc && $s{lc $_}}keys %s;
' ChaLlenge

Results:

ChaLlenge -> L

Example 3:

perl -MList::Util=maxstr -E '
$s{$_}++ for split "", $i=shift; say "$i -> ",  maxstr grep {$_ eq uc && $s{lc $_}}keys %s;
' The

Results:

The ->

The full code only adds a few checks.

 1  # Perl weekly challenge 264
 2  # Task 1:  Greatest English Letter
 3  #
 4  # See https://wlmb.github.io/2024/04/12/PWC264/#task-1-greatest-english-letter
 5  use v5.36;
 6  use List::Util qw(maxstr);
 7  die <<~"FIN" unless @ARGV;
 8      Usage: $0 S1 [S2...]
 9      to find the greatest English letter of each string S1, S2...
10      FIN
11  for(@ARGV){
12      warn("Only alphabetical characters allowed a..z A..Z"), next unless /^[a-zA-Z]+$/;
13      my %seen;
14      $seen{$_}++ for split "";
15      say "$_ -> ",  maxstr grep {$_ eq uc && $seen{lc $_}}keys %seen;
16  }
17  

Examples:

./ch-1.pl PeRlwEeKLy ChaLlenge The

Results:

PeRlwEeKLy -> L
ChaLlenge -> L
The ->

Task 2: Target Array

Submitted by: Mohammad Sajid Anwar
You are given two arrays of integers, @source and @indices. The @indices can only
contains integers 0 <= i < size of @source.

Write a script to create target array by insert at index $indices[i] the value
$source[i].

Example 1
Input: @source  = (0, 1, 2, 3, 4)
       @indices = (0, 1, 2, 2, 1)
Output: (0, 4, 1, 3, 2)

@source  @indices  @target
0        0         (0)
1        1         (0, 1)
2        2         (0, 1, 2)
3        2         (0, 1, 3, 2)
4        1         (0, 4, 1, 3, 2)
Example 2
Input: @source  = (1, 2, 3, 4, 0)
       @indices = (0, 1, 2, 3, 0)
Output: (0, 1, 2, 3, 4)

@source  @indices  @target
1        0         (1)
2        1         (1, 2)
3        2         (1, 2, 3)
4        3         (1, 2, 3, 4)
0        0         (0, 1, 2, 3, 4)
Example 3
Input: @source  = (1)
       @indices = (0)
Output: (1)

This may be solved by splicing the values into place. I assume the inputs are the source and the indices as space separated arrays. The result fits a oneliner.

Example 1:

perl -E '
@s=split " ", shift; @i=split " ", shift; splice @o, $i[$_],0,$s[$_] for 0..@i-1; say "s=(@s), i=(@i) -> (@o)";
' "0 1 2 3 4" "0 1 2 2 1"

Results:

s=(0 1 2 3 4), i=(0 1 2 2 1) -> (0 4 1 3 2)

Example 2:

perl -E '
@s=split " ", shift; @i=split " ", shift; splice @o, $i[$_],0,$s[$_] for 0..@i-1; say "s=(@s), i=(@i) -> (@o)";
' "1 2 3 4 0" "0 1 2 3 0"

Results:

s=(1 2 3 4 0), i=(0 1 2 3 0) -> (0 1 2 3 4)

Example 3:

perl -E '
@s=split " ", shift; @i=split " ", shift; splice @o, $i[$_],0,$s[$_] for 0..@i-1; say "s=(@s), i=(@i) -> (@o)";
' "1" "0"

Results:

s=(1), i=(0) -> (1)

The full code just adds some checks.

 1  # Perl weekly challenge 264
 2  # Task 2:  Target Array
 3  #
 4  # See https://wlmb.github.io/2024/04/12/PWC264/#task-2-target-array
 5  use v5.36;
 6  use experimental qw(for_list);
 7  LOOP: for my ($source, $indices)(@ARGV){
 8      my @source=split " ", $source;
 9      my @indices=split " ", $indices;
10      my @output;
11      for(0..@indices-1){
12  	warn("Index out of range"), next LOOP unless 0 <= $_ < @source;
13  	splice @output, $indices[$_],0,$source[$_];
14      }
15      say "source=(@source), indices=(@indices) -> (@output)";
16  }

Examples:

./ch-2.pl "0 1 2 3 4" "0 1 2 2 1" "1 2 3 4 0" "0 1 2 3 0" "1" "0"

Results:

source=(0 1 2 3 4), indices=(0 1 2 2 1) -> (0 4 1 3 2)
source=(1 2 3 4 0), indices=(0 1 2 3 0) -> (0 1 2 3 4)
source=(1), indices=(0) -> (1)

/;

Written on April 12, 2024