A password is considered strong if the below conditions are all met:
- It has at least 6characters and at most20characters.
- It contains at least one lowercase letter, at least one uppercase letter, and at least one digit.
- It does not contain three repeating characters in a row (i.e., "...aaa..."is weak, but"...aa...a..."is strong, assuming other conditions are met).
Given a string password, return the minimum number of steps required to make password strong. if password is already strong, return 0.
In one step, you can:
- Insert one character to password,
- Delete one character from password, or
- Replace one character of password with another character.
Example 1:
Input: password = "a"
Output: 5
Example 2:
Input: password = "aA1"
Output: 3
Example 3:
Input: password = "1337C0d3"
Output: 0
Constraints:
- 1 <= password.length <= 50
- passwordconsists of letters, digits, dot- '.'or exclamation mark- '!'.
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 | class Solution:
    type_sets = [
        set('abcdefghijklmnopqrstuvwxyz'),
        set('ABCDEFGHIJKLMNOPQRSTUFVWXYZ'),
        set('0123456789'),
    ]
    
    def strongPasswordChecker(self, password: str) -> int:
        chars = set(password)
        # Check rule 1
        num_req_inserts = max(0, 6 - len(password))
        num_req_deletes = max(0, len(password) - 20)
        # Check rule 2
        num_req_types = 0
        for t in self.type_sets:
            num_req_types += 0 if (chars & t) else 1
        # Check rule 3
        groups = [len(list(grp)) for _, grp in itertools.groupby(password)]
        for _ in range(num_req_deletes):
            # Apply best delete
            idx, _ = min(
                enumerate(groups),
                # Ignore groups of length < 3
                # 5 - it[1] > 2 when it[1] < 3
                key=lambda it: it[1] % 3 if it[1] >= 3 else 5,
            )
            groups[idx] -= 1
        num_req_group_replaces = sum(
            group // 3
            for group in groups
        )
        return (
            num_req_deletes
            + max(
                num_req_types,
                num_req_group_replaces,
                num_req_inserts,
                )
            )
 |