aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-287/peter-campbell-smith/blog.txt1
-rwxr-xr-xchallenge-287/peter-campbell-smith/perl/ch-1.pl69
-rwxr-xr-xchallenge-287/peter-campbell-smith/perl/ch-2.pl40
3 files changed, 110 insertions, 0 deletions
diff --git a/challenge-287/peter-campbell-smith/blog.txt b/challenge-287/peter-campbell-smith/blog.txt
new file mode 100644
index 0000000000..de7d8209d9
--- /dev/null
+++ b/challenge-287/peter-campbell-smith/blog.txt
@@ -0,0 +1 @@
+http://ccgi.campbellsmiths.force9.co.uk/challenge/287
diff --git a/challenge-287/peter-campbell-smith/perl/ch-1.pl b/challenge-287/peter-campbell-smith/perl/ch-1.pl
new file mode 100755
index 0000000000..4d674c0ee3
--- /dev/null
+++ b/challenge-287/peter-campbell-smith/perl/ch-1.pl
@@ -0,0 +1,69 @@
+#!/usr/bin/perl
+
+# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge
+
+use v5.26; # The Weekly Challenge - 2024-09-16
+use utf8; # Week 287 - task 1 - Strong password
+use warnings; # Peter Campbell Smith
+binmode STDOUT, ':utf8';
+
+strong_password('aaabbbcccccc', '4 triplets, no upper or digit');
+strong_password('123abcdef', 'no upper case');
+strong_password('abcdefghijkl', 'no upper or digit');
+strong_password('ABCD5aa6FGHI', 'no change needed');
+strong_password('Mi5', 'too short');
+strong_password('', 'null');
+
+sub strong_password {
+
+ my ($password, $comment, $steps, @upper, @lower, @digit, $props, $r, $insert, $length);
+
+ ($password, $comment) = @_;
+ $steps = 0;
+ @upper = ('A' .. 'Z');
+ @lower = ('a' .. 'z');
+ @digit = ('0' .. '9');
+
+ # stage 1 - deal with triplets
+ while (1) {
+ $props = assess($password);
+ $r = $props->{triplet};
+ last unless $r;
+ $insert = '';
+ do {
+ $insert = $digit[rand(10)] unless $props->{digit};
+ $insert = $lower[rand(26)] unless $props->{lower};
+ $insert = $upper[rand(26)] unless $insert;
+ } until $insert ne $r;
+ $password =~ s|$r$r$r|$r$r$insert$r|;
+ $steps ++;
+ }
+
+ # stage 2 - append any missing class of character
+ $length = length($password);
+ $password .= $lower[rand(26)] unless $props->{lower};
+ $password .= $upper[rand(26)] unless $props->{upper};
+ $password .= $digit[rand(10)] unless $props->{digit};
+
+ # stage 3 - pad if necessary to 6 chars
+ $password .= $lower[rand(26)] while length($password) < 6;
+ $steps += length($password) - $length;
+
+ say qq[\nInput: \$password = '$_[0]' ($comment)];
+ say qq[Output: '$password'] .
+ qq[ after $steps step] . ($steps == 1 ? '' : 's');
+}
+
+sub assess {
+
+ my ($password, %props);
+
+ # get properties of password
+ $password = $_[0];
+ $props{lower} = $password =~ m|[a-z]|;
+ $props{upper} = $password =~ m|[A-Z]|;
+ $props{digit} = $password =~ m|[0-9]|;
+ $props{triplet} = $password =~ m|(.)\1\1| ? $1 : '';
+ return \%props;
+}
+
diff --git a/challenge-287/peter-campbell-smith/perl/ch-2.pl b/challenge-287/peter-campbell-smith/perl/ch-2.pl
new file mode 100755
index 0000000000..e1ba919f76
--- /dev/null
+++ b/challenge-287/peter-campbell-smith/perl/ch-2.pl
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+
+# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge
+
+use v5.26; # The Weekly Challenge - 2024-09-16
+use utf8; # Week 287 - task 2 - Valid number
+use warnings; # Peter Campbell Smith
+binmode STDOUT, ':utf8';
+
+my @tests;
+
+say qq[\nValid numbers:\n \$str Valid?\n ----- ------];
+@tests = ('23', '-23', '+23', '34.1', '-34.1', '+34.1', '.7', '-.7', '23e0', '23e-1', '23E+2', '-23e10', '+34.5e-10');
+valid_number($_) for @tests;
+
+say qq[\nInvalid numbers:\n \$str Valid?\n ----- ------];
+@tests = ('two', '23-', '23.1.2', 'e', 'e1', '34e1.2', '34e++6', '.e5', '+.e5', '123E', '.', '.e6' );
+valid_number($_) for @tests;
+
+sub valid_number {
+
+ my ($str, $str2, $valid, $a, $b);
+
+ $str = $_[0];
+ $valid = 0;
+
+ # basic match $a------------ $b-----
+ if (($a, $b) = $str =~ m|^([-+]?\d*\.?\d*)([Ee]?.*)$|) {
+
+ # but if [Ee] is present it must be followed by optional sign and 1+ digits
+ $valid = 1 if ($b eq '' or ($a ne '' and $b =~ m|^[Ee][-+]?\d+$|));
+ }
+
+ # decimal point must be preceded or followed by a digit (or both)
+ if ($valid and $str =~ m|\.|) {
+ $valid = 0 unless ($str =~ m|\d\.| or $str =~ m|\.\d|);
+ }
+
+ printf("%10s %10s\n", $str, ('false', 'true')[$valid]);
+}