<p>A password is considered strong if the below conditions are all met:</p>

<ul>
	<li>It has at least <code>6</code> characters and at most <code>20</code> characters.</li>
	<li>It contains at least <strong>one lowercase</strong> letter, at least <strong>one uppercase</strong> letter, and at least <strong>one digit</strong>.</li>
	<li>It does not contain three repeating characters in a row (i.e., <code>&quot;B<u><strong>aaa</strong></u>bb0&quot;</code> is weak, but <code>&quot;B<strong><u>aa</u></strong>b<u><strong>a</strong></u>0&quot;</code> is strong).</li>
</ul>

<p>Given a string <code>password</code>, return <em>the minimum number of steps required to make <code>password</code> strong. if <code>password</code> is already strong, return <code>0</code>.</em></p>

<p>In one step, you can:</p>

<ul>
	<li>Insert one character to <code>password</code>,</li>
	<li>Delete one character from <code>password</code>, or</li>
	<li>Replace one character of <code>password</code> with another character.</li>
</ul>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre><strong>Input:</strong> password = "a"
<strong>Output:</strong> 5
</pre><p><strong class="example">Example 2:</strong></p>
<pre><strong>Input:</strong> password = "aA1"
<strong>Output:</strong> 3
</pre><p><strong class="example">Example 3:</strong></p>
<pre><strong>Input:</strong> password = "1337C0d3"
<strong>Output:</strong> 0
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= password.length &lt;= 50</code></li>
	<li><code>password</code> consists of letters, digits, dot&nbsp;<code>&#39;.&#39;</code> or exclamation mark <code>&#39;!&#39;</code>.</li>
</ul>

class Solution:
    def strongPasswordChecker(self, password: str) -> int:
        n = len(password)
        
        # Check for character type presence
        has_lower = any(c.islower() for c in password)
        has_upper = any(c.isupper() for c in password)
        has_digit = any(c.isdigit() for c in password)
        
        # Count the missing types
        missing_types = 3 - (has_lower + has_upper + has_digit)
        
        if n < 6:
            # If length is less than 6, need to insert characters
            return max(missing_types, 6 - n)
        
        # Identify repeating sequences
        repeats = [len(list(group)) for char, group in itertools.groupby(password)]
        
        if n <= 20:
            # Handle normal passwords (6 <= length <= 20)
            replace = sum(length // 3 for length in repeats)
            return max(missing_types, replace)
        
        # Handle long passwords (length > 20)
        excess = n - 20
        
        # Count the number of changes needed
        changes = 0
        one_change = 0
        two_changes = 0
        
        for length in repeats:
            if length >= 3:
                changes += length // 3
                if length % 3 == 0:
                    one_change += 1
                elif length % 3 == 1:
                    two_changes += 1
        
        # Use excess deletions to reduce the number of changes needed
        if excess <= one_change:
            changes -= excess
        elif excess <= one_change + 2 * two_changes:
            changes -= one_change
            changes -= (excess - one_change) // 2
        else:
            changes -= one_change + two_changes
            changes -= (excess - one_change - 2 * two_changes) // 3
        
        return excess + max(changes, missing_types)

# Example usage
solution = Solution()
print(solution.strongPasswordChecker("a"))  # Expected output: 5
print(solution.strongPasswordChecker("aA1"))  # Expected output: 3
print(solution.strongPasswordChecker("1337C0d3"))  # Expected output: 0
print(solution.strongPasswordChecker("bbaaaaaaaaaaaaaaacccccc"))  # Expected output: 8
16700