Perl Weekly Challenge 282.

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

Task 1: Good Integer

Submitted by: Mohammad Sajid Anwar
You are given a positive integer, $int, having 3 or more digits.

Write a script to return the Good Integer in the given integer or -1 if none found.

A good integer is exactly three consecutive matching digits.

Example 1
Input: $int = 12344456
Output: "444"
Example 2
Input: $int = 1233334
Output: -1
Example 3
Input: $int = 10020003
Output: "000"

I can capture with a regular expression a single character, then two copies of the same character and finally then an arbitrary number of repetitions of the same character. If the last group is empty, I have found a good integer. If not, I can substitute the whole expression and the preceding substring by an empty string and start again, until there are no more groups of three consecutive characters, in which case the answer is -1. I use two loops, one for the input and one for the match attempts. I use the LABEL.... next LABEL construction to gracefully jump out of the inner loop. The code fits a oneliner

Examples:

perl -E '
A:for(@ARGV){my $x=$_;while(s/.*?((.)\2\2(\2*))//){say("$x -> $1"), next A if $3 eq ""} say "$x -> -1"}
' 12344456 1233334 10020003

Results:

12344456 -> 444
1233334 -> -1
10020003 -> 000

The full code is similar:

 1  # Perl weekly challenge 282
 2  # Task 1:  Good Integer
 3  #
 4  # See https://wlmb.github.io/2024/08/11/PWC282/#task-1-good-integer
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV;
 7      Usage: $0 N1 N2...
 8      to find good integers within the numbers N1 N2...
 9      FIN
10  ARG: for(@ARGV){
11      my $arg=$_;
12      warn "Expected only digits: $_" unless /^\d+$/;
13      while(s/.*?((.)\2\2(\2*))//){
14          say("$arg -> $1"), next ARG if $3 eq "";
15      }
16      say "$arg -> -1"
17  }

Examples:

./ch-1.pl 12344456 1233334 10020003

Results:

12344456 -> 444
1233334 -> -1
10020003 -> 000

Task 2: Changing Keys

Submitted by: Mohammad Sajid Anwar
You are given an alphabetic string, $str, as typed by user.

Write a script to find the number of times user had to change the key to type the
given string. Changing key is defined as using a key different from the last used
key. The shift and caps lock keys won’t be counted.

Example 1
Input: $str = 'pPeERrLl'
Ouput: 3

p -> P : 0 key change
P -> e : 1 key change
e -> E : 0 key change
E -> R : 1 key change
R -> r : 0 key change
r -> L : 1 key change
L -> l : 0 key change
Example 2
Input: $str = 'rRr'
Ouput: 0
Example 3
Input: $str = 'GoO'
Ouput: 1

I can convert the string to lowercase and interpret same key as same character. I can remove repeated characters using regular expressions and then count how many distinct characters remain and subtract 1 to get the number of changes, one between each pair of consecutive characters. The result fits a half-liner.

Examples:

perl -E '
for(@ARGV){$x=$_; $_=lc; s/(.)\1+/$1/g; say "$x -> ", length($_)-1}
' pPeERrLl rRr GoO

Results:

pPeERrLl -> 3
rRr -> 0
GoO -> 1

The full code is similar.

 1  # Perl weekly challenge 282
 2  # Task 2:  Changing Keys
 3  #
 4  # See https://wlmb.github.io/2024/08/11/PWC282/#task-2-changing-keys
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV;
 7      Usage: $0 S1 S2...
 8      to count how many key changes are required for each character in strings S1 S2...
 9      FIN
10  for(@ARGV){
11      warn("Expected alphabetical string: $_"), next unless /^[a-zA-Z]+$/;
12      my $arg=$_;
13      $_=lc;
14      s/(.)\1+/$1/g;
15      say "$arg -> ", length($_)-1
16  }

Example:

./ch-2.pl pPeERrLl rRr GoO

Results:

pPeERrLl -> 3
rRr -> 0
GoO -> 1

/;

Written on August 11, 2024