From 5d75ab8c8d1460270688b279a857adf0d03ae44b Mon Sep 17 00:00:00 2001 From: robbie-hatley Date: Mon, 29 Jan 2024 18:47:42 -0800 Subject: Robbie Hatley's Perl solutions to The Weekly Challenge #254. --- challenge-254/robbie-hatley/blog.txt | 1 + challenge-254/robbie-hatley/perl/ch-1.pl | 120 +++++++++++++++++++++++++++++++ challenge-254/robbie-hatley/perl/ch-2.pl | 107 +++++++++++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 challenge-254/robbie-hatley/blog.txt create mode 100755 challenge-254/robbie-hatley/perl/ch-1.pl create mode 100755 challenge-254/robbie-hatley/perl/ch-2.pl diff --git a/challenge-254/robbie-hatley/blog.txt b/challenge-254/robbie-hatley/blog.txt new file mode 100644 index 0000000000..ce56482178 --- /dev/null +++ b/challenge-254/robbie-hatley/blog.txt @@ -0,0 +1 @@ +https://hatley-software.blogspot.com/2024/01/robbie-hatleys-solutions-to-weekly_29.html \ No newline at end of file diff --git a/challenge-254/robbie-hatley/perl/ch-1.pl b/challenge-254/robbie-hatley/perl/ch-1.pl new file mode 100755 index 0000000000..a12244626d --- /dev/null +++ b/challenge-254/robbie-hatley/perl/ch-1.pl @@ -0,0 +1,120 @@ +#!/usr/bin/env perl + +=pod + +-------------------------------------------------------------------------------------------------------------- +COLOPHON: +This is a 110-character-wide Unicode UTF-8 Perl-source-code text file with hard Unix line breaks ("\x0A"). +¡Hablo Español! Говорю Русский. Björt skjöldur. ॐ नमो भगवते वासुदेवाय. 看的星星,知道你是爱。麦藁雪、富士川町、山梨県。 + +-------------------------------------------------------------------------------------------------------------- +TITLE BLOCK: +Solutions in Perl for The Weekly Challenge 254-1. +Written by Robbie Hatley on Sun Jan 28, 2023. + +-------------------------------------------------------------------------------------------------------------- +PROBLEM DESCRIPTION: +Task 254-1: Three Power +Submitted by: Mohammad S Anwar +You are given a positive integer, $n. Write a script to return +true if the given integer is a power of three otherwise return +false. + +Example 1: +Input: $n = 27 +Output: true +27 = 3 ^ 3 + +Example 2: +Input: $n = 0 +Output: true +0 = 0 ^ 3 + +Example 3: +Input: $n = 6 +Output: false + +-------------------------------------------------------------------------------------------------------------- +PROBLEM NOTES: +First of all, I had to think hard whether "Three Power" means "$x**3" or "3**$x". But the latter would be +"3 to the $x power", whereas the former is "$x to the 3 power", so I think "Three Power" means "3**$x". +This is also corroborated by Example #2, which states that 0 is a "Three Power" because "0 = 0^3", +not "0 = 3^0" which is false (3^0 = 1). So this problem boils down to "Given an integer x, does there exist +an integer r such that r^3 = x?" + +There are many ways to solve this problem: Factoring, trial-and-error, subtracting integer portion of cube +root from cube root, cubing the integer portion of the cube root, etc. + +I initially chose to use a method that's simpler than any of those: If the cube root of $x is an integer, +then $x is a perfect cube, else it isn't. + +However, I ran into a complicating factor with that approach: C (and hence Perl) fails to correctly implement +a**b if a is a negative real number and b is 1/n where n is an odd integer greater than 1 (3, 5, 7...). + +So I changed my approach to the following: I first calculate the icr (integer portion of cube root) of x. +Then I check to see if icr(x)^3 is equal to x. If it is, $x is a perfect cube, else it's not. + +With that in-mind, I created these subs: + +# Return the integer portion of the cube root of any integer: +sub icr ($x) { + my $r = 0; + if ($x < 0) {--$r until ($r-1)*($r-1)*($r-1) < $x} + else {++$r until ($r+1)*($r+1)*($r+1) > $x} + return $r; +} + +# Is a given integer a perfect cube? +sub is_cube ($x) { + return icr($x)*icr($x)*icr($x) == $x; +} + +-------------------------------------------------------------------------------------------------------------- +IO NOTES: +Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a +single-quoted array of integers in proper Perl syntax, like so: +./ch-1.pl '(-28, -27, -26, -9, -8, -7, -1, 0, 1, 7, 8, 9, 26, 27, 28)' + +Output is to STDOUT and will be each input followed by the corresponding output. + +=cut + +# ------------------------------------------------------------------------------------------------------------ +# PRAGMAS AND MODULES USED: + +use v5.38; + +# ------------------------------------------------------------------------------------------------------------ +# SUBROUTINES: + +# Is a given string a decimal representation of an integer? +sub is_int ($x) { + return $x =~ m/^-[1-9]\d*$|^0$|^[1-9]\d*$/; +} + +# Return the integer portion of the cube root of any integer: +sub icr ($x) { + my $r = 0; + if ($x < 0) {--$r until ($r-1)*($r-1)*($r-1) < $x} + else {++$r until ($r+1)*($r+1)*($r+1) > $x} + return $r; +} + +# Is a given integer a perfect cube? +sub is_cube ($x) { + return icr($x)*icr($x)*icr($x) == $x; +} + +# ------------------------------------------------------------------------------------------------------------ +# MAIN BODY OF PROGRAM: + +# Inputs: +my @ints = @ARGV ? eval($ARGV[0]) : (27, 0, 6); + +# Main loop: +for my $int (@ints) { + !is_int($int) and say "Error: $int is not an integer" and next; + is_cube($int) and say "$int is a perfect cube." + or say "$int is NOT a perfect cube."; +} +exit; diff --git a/challenge-254/robbie-hatley/perl/ch-2.pl b/challenge-254/robbie-hatley/perl/ch-2.pl new file mode 100755 index 0000000000..62755b2266 --- /dev/null +++ b/challenge-254/robbie-hatley/perl/ch-2.pl @@ -0,0 +1,107 @@ +#!/usr/bin/env -S perl -CSDA + +=pod + +-------------------------------------------------------------------------------------------------------------- +COLOPHON: +This is a 110-character-wide Unicode UTF-8 Perl-source-code text file with hard Unix line breaks ("\x0A"). +¡Hablo Español! Говорю Русский. Björt skjöldur. ॐ नमो भगवते वासुदेवाय. 看的星星,知道你是爱。麦藁雪、富士川町、山梨県。 + +-------------------------------------------------------------------------------------------------------------- +TITLE BLOCK: +Solutions in Perl for The Weekly Challenge 254-2. +Written by Robbie Hatley on Sun Jan 28, 2023. + +-------------------------------------------------------------------------------------------------------------- +PROBLEM DESCRIPTION: +Task 254-2: Reverse Vowels +Submitted by: Mohammad S Anwar +You are given a string, $s. Write a script to reverse all the +vowels (a, e, i, o, u) in the given string. +[But keep the case. ~RH] + +Example 1: +Input: $s = "Raku" +Output: "Ruka" + +Example 2 +Input: $s = "Perl" +Output: "Perl" + +Example 3 +Input: $s = "Julia" +Output: "Jaliu" + +Example 4 +Input: $s = "Uiua" +Output: "Auiu" + +-------------------------------------------------------------------------------------------------------------- +PROBLEM NOTES: +This problem is quite tricky, as it involves reversing a non-contiguous slice of a word without altering the +remaining characters, and while keeping track of case. I used the following approach: +1. Riffle through the word, recording arrays of these two things for each vowel: + a. index + b. vowel +4. Riffle through the array of vowel indices. For each index, substr the character at that index in the word + to an appropriately-cased version of the letter popped from the right end of the vowels array. + +-------------------------------------------------------------------------------------------------------------- +IO NOTES: +Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a +single-quoted array of double-quoted strings, in proper Perl syntax, like so: +./ch-2.pl '("insouciant", "Robbie Hatley", "She didn’t like fish.", "I ate a dog!")' + +Output is to STDOUT and will be each input followed by the corresponding output. + +=cut + +# ------------------------------------------------------------------------------------------------------------ +# PRAGMAS AND MODULES USED: + +use v5.38; +use strict; +use warnings; +use utf8; +use warnings FATAL => 'utf8'; +use Sys::Binmode; + +# ------------------------------------------------------------------------------------------------------------ +# SUBROUTINES: + +# Is a given character a vowel? +sub is_vowel ($x) {return $x =~ m/^[aeiouAEIOU]$/} + +# Return the case of a given character (1 for [A-Z], 0 for all else): +sub case ($x) {return $x =~ m/^[A-Z]$/} + +# Reverse the vowels of a string while keeping case: +sub reverse_vowels ($x) { + my @indices; my @vowels; + for ( my $i = 0 ; $i < length($x) ; ++$i ) { + my $l = substr $x, $i, 1; + if ( is_vowel $l ) { + push @indices, $i; + push @vowels, $l; + } + } + for my $index ( @indices ) { + if ( case(substr($x, $index, 1)) ) {substr $x, $index, 1, uc(pop @vowels)} + else {substr $x, $index, 1, lc(pop @vowels)} + } + return $x; +} + +# ------------------------------------------------------------------------------------------------------------ +# MAIN BODY OF PROGRAM: + +# Inputs: +my @strings = @ARGV ? eval($ARGV[0]) : ("Raku", "Perl", "Julia", "Uiua"); + +# Main loop: +for my $fwdstr (@strings) { + say ''; + my $revstr = reverse_vowels($fwdstr); + say "String with original vowels = $fwdstr"; + say "String with reversed vowels = $revstr"; +} -- cgit From e6b47202299d4b82b954e1f59fd79eebaf5721a0 Mon Sep 17 00:00:00 2001 From: robbie-hatley Date: Mon, 29 Jan 2024 19:02:39 -0800 Subject: Fixed comment error in 254-1. --- challenge-254/robbie-hatley/perl/ch-1.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/challenge-254/robbie-hatley/perl/ch-1.pl b/challenge-254/robbie-hatley/perl/ch-1.pl index a12244626d..e3165dde06 100755 --- a/challenge-254/robbie-hatley/perl/ch-1.pl +++ b/challenge-254/robbie-hatley/perl/ch-1.pl @@ -36,8 +36,8 @@ Output: false -------------------------------------------------------------------------------------------------------------- PROBLEM NOTES: -First of all, I had to think hard whether "Three Power" means "$x**3" or "3**$x". But the latter would be -"3 to the $x power", whereas the former is "$x to the 3 power", so I think "Three Power" means "3**$x". +First of all, I had to think hard whether "Three Power" means "x^3" or "3^x". But the latter would be +"3 to the x power", whereas the former is "x to the 3 power", so I think "Three Power" means "x^3". This is also corroborated by Example #2, which states that 0 is a "Three Power" because "0 = 0^3", not "0 = 3^0" which is false (3^0 = 1). So this problem boils down to "Given an integer x, does there exist an integer r such that r^3 = x?" -- cgit From c871b3b40ff173b7fa3ac03625f46930d770886e Mon Sep 17 00:00:00 2001 From: robbie-hatley Date: Mon, 29 Jan 2024 19:06:45 -0800 Subject: Fixed spacing error in 254-1. --- challenge-254/robbie-hatley/perl/ch-1.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/challenge-254/robbie-hatley/perl/ch-1.pl b/challenge-254/robbie-hatley/perl/ch-1.pl index e3165dde06..b409d14c7e 100755 --- a/challenge-254/robbie-hatley/perl/ch-1.pl +++ b/challenge-254/robbie-hatley/perl/ch-1.pl @@ -38,6 +38,7 @@ Output: false PROBLEM NOTES: First of all, I had to think hard whether "Three Power" means "x^3" or "3^x". But the latter would be "3 to the x power", whereas the former is "x to the 3 power", so I think "Three Power" means "x^3". + This is also corroborated by Example #2, which states that 0 is a "Three Power" because "0 = 0^3", not "0 = 3^0" which is false (3^0 = 1). So this problem boils down to "Given an integer x, does there exist an integer r such that r^3 = x?" -- cgit