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`

or`E`

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.