22 September 2024 | Challenge 287 |
Common Passwords
Task 1: Strong Password
Submitted by: Mohammad Sajid Anwar
You are given a string, $str
.
Write a program to return the minimum number of steps required to make the given string very strong password. If it is already strong then return 0.
Criteria:
- It must have at least 6 characters.
- It must contains at least one lowercase letter, at least one upper case letter and at least one digit.
- It shouldn’t contain 3 repeating characters in a row.
Following can be considered as one step:
- Insert one character
- Delete one character
- Replace one character with another
Example 1
Input: $str = "a"
Output: 5
Example 2
Input: $str = "aB2"
Output: 3
Example 3
Input: $str = "PaaSW0rd"
Output: 0
Example 4
Input: $str = "Paaasw0rd"
Output: 1
Example 5
Input: $str = "aaaaa"
Output: 3
Solution
We may calculate three measures that give the number of steps that have to be performed such that the corresponding criterion is satisfied:
- The number of characters below the minimum length.
- The number of missing character classes.
- The number of changes to break all groups of three repeated characters.
With a single step, more than one measure may be reduced:
- Inserting a character increments the string length and introduces a new character class.
- Changing a character breaks a series of up to five repeated characters and introduces a new character class.
The only anomaly here is a string made of a sequence of five repeated characters:
- Changing one character breaks the sequence but does not extend the string.
- Inserting one character extends the string but doesn’t break the sequence.
But such a string consists of only one character class and thus two steps are required anyway.
Thus the maximum over all three measures gives the required number of steps in all cases.
use strict;
use warnings;
use experimental 'signatures'
use List::Util qw(reduce max);
sub strong_password ($str) {
max +(length($str) < 6 ? 6 - length($str) : 0),
(3 - grep {eval "\$str =~ tr/$_//"} qw(a-z A-Z 0-9)),
(reduce {$a + int length($b) / 3} 0, $str =~ /((.)\2{2,})/g);
}
See the full solution to task 1.
Task 2: Valid Number
Submitted by: Mohammad Sajid Anwar
You are given a string, $str
.
Write a script to find if it is a valid number.
Conditions for a valid number:
- An integer number followed by an optional exponent.
- A decimal number followed by an optional exponent.
- An integer number is defined with an optional sign
-
or+
followed by digits.
Decimal Number:
A decimal number is defined with an optional sign -
or +
followed by one of the following definitions:
- Digits followed by a dot
.
. - Digits followed by a dot
.
followed by digits. - A dot
.
followed by digits.
Exponent:
- An exponent is defined with an exponent notation
e
orE
followed by an integer number.
Example 1
Input: $str = "1"
Output: true
Example 2
Input: $str = "a"
Output: false
Example 3
Input: $str = "."
Output: false
Example 4
Input: $str = "1.2e4.2"
Output: false
Example 5
Input: $str = "-1."
Output: true
Example 6
Input: $str = "+1E-8"
Output: true
Example 7
Input: $str = ".44"
Output: true
Solution
This task is what Regex::Common
was made for.
use strict;
use warnings;
use Regexp::Common;
sub valid_number {
shift =~ /^$RE{num}{real}\z/;
}
See the full solution to task 2.
If you have a question about this post or if you like to comment on it, feel free to open an issue in my github repository.