Everything Under The Sun Is In Tune: Weekly Challenge #264
But the Sun is eclipsed by the moon.
This is Weekly Challenge #264
This week’s challenge came out on the day of the 2024 Total Solar Eclipse, and I live maybe a half-hour drive outside of the zone of totality, so instead of jumping on it, taking care of the Challenge first thing, I drove to a road next to a field in Indiana and saw my first total eclipse. The next ones we could see in the US will be in 2044 and 2045, so I took my chance while I could.
Holding eclipse glasses over your camera phone will not get a good photo of the corona.
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.
Let’s Talk About It
We’re looking for a matched pair of characters, uppercase and lowercase. So, we need a way to mark for each letter if theres both an uppercase and a lowercase. As I often do, I store things in a hash. If there’s no U
in the hash value and the letter is uppercase, I append the U
, and same with L
for lowercase. And then, use grep to find the solution, if any.
To get into the habit, I used fold case, or fc
, rather than uc
or lc
.
Show Me The Code!
#!/usr/bin/env perl
use strict;
use warnings;
use experimental qw{ fc postderef say signatures state };
my @examples = (
'PeRlwEeKLy',
'ChaLlenge',
'The',
);
for my $example (@examples) {
my $output = greatest_letter($example);
say <<"END";
Input: \$str = "$example"
Output: "$output"
END
}
sub greatest_letter ($str) {
my @letters = split //, $str;
my %hash;
for my $l (@letters) {
my $L = uc $l;
$hash{$L} ||= '';
if ( $L eq uc $l ) {
if ( $L eq $l ) { # uppercase
if ( $hash{$L} !~ /U/ ) {
$hash{$L} .= 'U';
}
}
else { # lowercase
if ( $hash{$L} !~ /L/ ) {
$hash{$L} .= 'L';
}
}
}
}
my @contenders =
grep { length $hash{$_} == 2 }
sort { $b cmp $a }
keys %hash;
return @contenders ? shift @contenders : '';
}
$ ./ch-1.pl
Input: $str = "PeRlwEeKLy"
Output: "L"
Input: $str = "ChaLlenge"
Output: "L"
Input: $str = "The"
Output: ""
Task 2: Target Array
Submitted by: Mohammad Sajid Anwar
You are given two arrays of integers,
@source
and@indices
. The @indices can only contains integers0 <= i < size of @source
.Write a script to create target array by insert at index
$indices[i]
the value$source[i]
.
Let’s Talk About It
This forced me to learn splice
, which I literally have never done before. I have played with splices, like @array = @array[0..3], 8 , @array[4..8]
, but not using the splice
function, which clearly makes things so much easier.
Show Me The Code!
#!/usr/bin/env perl
use strict;
use warnings;
use experimental qw{ say postderef signatures state };
my @examples = (
{ source => [ 0, 1, 2, 3, 4 ], indices => [ 0, 1, 2, 2, 1 ] },
{ source => [ 1, 2, 3, 4, 0 ], indices => [ 0, 1, 2, 3, 0 ] },
{ source => [1], indices => [0] },
{ source => [ 9, 0, 1, 2, 5 ], indices => [ 2, 1, 1, 2, 0 ] },
);
for my $example (@examples) {
my @output = target_array($example);
my $output = join ', ', @output;
my $source = join ', ', $example->{source}->@*;
my $indices = join ', ', $example->{indices}->@*;
say <<"END";
Input: \@source = ($source)
\@indices = ($indices)
Output: [ $output ]
END
}
sub target_array ($obj) {
my @source = $obj->{source}->@*;
my @indices = $obj->{indices}->@*;
my @target;
for my $k ( 0 .. $#source ) {
my $s = $source[$k];
my $i = $indices[$k];
my @input = ($s);
push @input, $target[$i]
if defined $target[$i];
splice( @target, $i, 1, @input );
}
return @target;
}
$ ./ch-2.pl
Input: @source = (0, 1, 2, 3, 4)
@indices = (0, 1, 2, 2, 1)
Output: [ 0, 4, 1, 3, 2 ]
Input: @source = (1, 2, 3, 4, 0)
@indices = (0, 1, 2, 3, 0)
Output: [ 0, 1, 2, 3, 4 ]
Input: @source = (1)
@indices = (0)
Output: [ 1 ]
Input: @source = (9, 0, 1, 2, 5)
@indices = (0, 1, 2, 1, 2)
Output: [ 9, 2, 5, 0, 1 ]