A password is considered strong if the below conditions are all met:


	It has at least 6 characters and at most 20 characters.
	It contains at least one lowercase letter, at least one uppercase letter, and at least one digit.
	It does&nbsp;not contain three repeating characters in a row (i.e.,&nbsp;"...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&nbsp;one character of password with another character.


&nbsp;
Example 1:
Input: password = "a"
Output: 5
Example 2:
Input: password = "aA1"
Output: 3
Example 3:
Input: password = "1337C0d3"
Output: 0

&nbsp;
Constraints:


	1 &lt;= password.length &lt;= 50
	password consists of letters, digits, dot&nbsp;'.' or exclamation mark '!'.


class Solution:
    def strongPasswordChecker(self, password: str) -> int:
        #vimla_kushwaha
        s = password
        missing_type = 3
        if any('a' <= c <= 'z' for c in s): missing_type -= 1
        if any('A' <= c <= 'Z' for c in s): missing_type -= 1
        if any(c.isdigit() for c in s): missing_type -= 1

        change = 0
        one = two = 0
        p = 2
        while p < len(s):
            if s[p] == s[p-1] == s[p-2]:
                length = 2
                while p < len(s) and s[p] == s[p-1]:
                    length += 1
                    p += 1
                    
                change += length // 3
                if length % 3 == 0: one += 1
                elif length % 3 == 1: two += 1
            else:
                p += 1
        
        if len(s) < 6:
            return max(missing_type, 6 - len(s))
        elif len(s) <= 20:
            return max(missing_type, change)
        else:
            delete = len(s) - 20
            
            change -= min(delete, one)
            change -= min(max(delete - one, 0), two * 2) // 2
            change -= max(delete - one - 2 * two, 0) // 3
                
            return int(delete + max(missing_type, change))
class Solution {
    private static final int MIN_LENGTH = 6;
    private static final int MAX_LENGTH = 20;

    public int strongPasswordChecker(String password) {
        int numMissingComponents = getNumberOfMissingComponents(password);
        int n = password.length();

        if (n < MIN_LENGTH) {
            return Math.max(numMissingComponents, MIN_LENGTH - n);
        }

        List<Integer> repeats = buildRepeatList(password);

        int over = Math.max(0, n - MAX_LENGTH);
        int numRemoval = over;

        // use overage for repeat % 3 == 0 case. One removal would reduce one replacement
        for (int i = 0; i < repeats.size() && over > 0; i++) {
            int repeat = repeats.get(i);
            if (repeat >= 3 && repeat % 3 == 0) {
                repeats.set(i, repeat - 1);
                over--;
            }
        }
        // use overage for repeat % 3 == 1 case. Two removal would reduce one replacement
        for (int i = 0; i < repeats.size() && over > 0; i++) {
            int repeat = repeats.get(i);
            if (repeat >= 3 && repeat % 3 == 1) {
                repeats.set(i, repeat - Math.min(over, 2));
                over -= Math.min(over, 2);
            }
        }

        int numReplace = 0;
        for (int repeat : repeats) {
            if (over > 0 && repeat >= 3) {
                int reduce = Math.min(over, repeat - 2);
                over -= reduce;
                repeat -= reduce;
            }
            if (repeat >= 3) {
                numReplace += repeat / 3;
            }
        }

        return Math.max(numReplace, numMissingComponents) + numRemoval;
    }

    private List<Integer> buildRepeatList(String password) {
        List<Integer> repeats = new ArrayList<>();
        for (int i = 0; i < password.length(); i++) {
            if (i == 0 || password.charAt(i) != password.charAt(i - 1)) {
                repeats.add(1);
            } else {
                int last = repeats.size() - 1;
                repeats.set(last, repeats.get(last) + 1);
            }
        }
        return repeats;
    }

    private int getNumberOfMissingComponents(String password) {
        int digit = 1;
        int upper = 1;
        int lower = 1;
        for (char c: password.toCharArray()) {
            if (Character.isDigit(c)) {
                digit = 0;
            }
            if (Character.isLowerCase(c)) {
                lower = 0;
            }
            if (Character.isUpperCase(c)) {
                upper = 0;
            }
        }
        return digit + upper + lower;
    }
}
class Solution {
public:
    int strongPasswordChecker(string password) {

if (password.size()<=2) return (6-password.size());
    else
    {
        //is first condition met?
        int sizeissue=0;
        if (password.size()<6)
            sizeissue=password.size()-6;
        else if(password.size()>20) sizeissue=password.size()-20;

        //is second condition met?
        int chtype=0, u=1,l=1,d=1;

        if(none_of(password.begin(), password.end(), &::isupper)) { chtype++; u=0;}
        if(none_of(password.begin(), password.end(), &::islower)) { chtype++; l=0;}
        if(none_of(password.begin(), password.end(), &::isdigit)) { chtype++; d=0;}

        //is the third condition met? Note there are 26 letter, the string is constrained under 50, so realistically you can always find some 'other' character not included previously in the string to break the password apart so the consecutive characters are split apart. So need to find the largest sets of consecutive characters or 'blocks', and for these the min is (size of block (-1 if even)/2?
        unsigned int output=0, i=0, start,end,issuethree=0;
        char c;

        if (sizeissue<0)
            {
                while (i<(password.size()-2))
                { if (password[i]==password[i+1]&&password[i]==password[i+2])
                    { start=i;
                        c=password[i]; i++;
                        while (c==password[i+2]&&i<(password.size()-2)) i++;
                        end=i+1;
                        i=end+1;

                        //what would the amount of changes be needed?

                        issuethree=(end-start+1)/3;

                        // add the latest issue to total output
                        output=output+issuethree;

                        // check if the missing second condition issue could resolve any of this
                        if(chtype>=1)
                        {if(islower(c)&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                        if(islower(c)&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }

                        if(isupper(c)&&(l==0)) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }
                        if(isupper(c)&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }

                        if(isxdigit(c)&&(l==0)) {chtype--;l=1;issuethree--;}
                        if(isxdigit(c)&&(u==0)&&issuethree>0) {chtype--;u=1;issuethree--; if(sizeissue<0) sizeissue++; }

                        if(c=='!'&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                        if(c=='!'&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }
                        if(c=='!'&&(l==0)&&issuethree>0) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }

                        if(c=='.'&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                        if(c=='.'&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }
                        if(c=='.'&&(l==0)&&issuethree>0) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }
                        }

                        //check first issue would resolve this
                        if((-sizeissue)<=issuethree) sizeissue=0; //e.g. aaa
                        else sizeissue=sizeissue+issuethree; //don't think this option is possible?

                    }
                    else i++;
                }
                if (chtype>0 && sizeissue<0)
                    {if (chtype>abs(sizeissue)) sizeissue=0;
                    else sizeissue=sizeissue+chtype;}
            }

        else if (sizeissue==0)
                {while (i<(password.size()-2))
                    { if (password[i]==password[i+1]&&password[i]==password[i+2])
                        { start=i;
                            c=password[i]; i++;
                            while (c==password[i+2]&&i<(password.size()-2)) i++;
                            end=i+1;
                            i=end+1;

                            //what would the amount of changes be needed?

                            issuethree=(end-start+1)/3;

                            // add the latest issue to total output
                            output=output+issuethree;

                            // check if the missing second condition issue could resolve any of this
                            if(chtype>=1)
                            {if(islower(c)&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                            if(islower(c)&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }

                            if(isupper(c)&&(l==0)) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }
                            if(isupper(c)&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }

                            if(isxdigit(c)&&(l==0)) {chtype--;l=1;issuethree--;}
                            if(isxdigit(c)&&(u==0)&&issuethree>0) {chtype--;u=1;issuethree--; if(sizeissue<0) sizeissue++; }

                            if(c=='!'&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                            if(c=='!'&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }
                            if(c=='!'&&(l==0)&&issuethree>0) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }

                            if(c=='.'&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                            if(c=='.'&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }
                            if(c=='.'&&(l==0)&&issuethree>0) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }

                            }

                         }
                        else i++;

                    }
                }

        else if (sizeissue>0)
                {int v[3],mod;
                    v[0]=0; v[1]=0; v[2]=0;
                    //have a vector where it says how many extra characters at the end of a block; e.g. aaa aa = v[2]=1; and in issue three how many blocks;
                    while (i<(password.size()-2))
                        { if (password[i]==password[i+1]&&password[i]==password[i+2])
                            { start=i;
                                c=password[i]; i++;
                                while (c==password[i+2]&&i<(password.size()-2)) i++;
                                end=i+1;
                                i=end+1;

                                issuethree=issuethree+(end-start+1)/3;
                                mod=(end-start+1)%3;
                                v[mod]=v[mod]+1;
                                }

                            else i++;
                        }
                    output=issuethree;

                    //delete efficiently to ensure most 'blocks of 3' are removed.
                    while (sizeissue>=1&&v[0]>0)
                    {sizeissue=sizeissue-1; v[0]--; issuethree--;}
                    while (sizeissue>=2&&v[1]>0)
                    {sizeissue=sizeissue-2; v[1]--; output=output+1; issuethree--;}
                    while (sizeissue>=3&&v[2]>0)
                    {sizeissue=sizeissue-3; v[2]--; output=output+2; issuethree--;}
                    while(sizeissue>=3&&issuethree>0)
                    {sizeissue=sizeissue-3; issuethree--; output=output+2;}

                    i=0;
                        // check if the missing second condition issue could resolve any of this
                    {while (i<(password.size()-2) && issuethree>0)
                        { if (password[i]==password[i+1]&&password[i]==password[i+2])
                            { start=i;
                                c=password[i]; i++;
                                while (c==password[i+2]&&i<(password.size()-2)) i++;
                                end=i+1;
                                i=end+1;

                                // check if the missing second condition issue could resolve any of this
                                if(chtype>=1)
                                {if(islower(c)&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                                    if(islower(c)&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }

                                    if(isupper(c)&&(l==0)) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }
                                    if(isupper(c)&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }

                                    if(isxdigit(c)&&(l==0)) {chtype--;l=1;issuethree--;}
                                    if(isxdigit(c)&&(u==0)&&issuethree>0) {chtype--;u=1;issuethree--; if(sizeissue<0) sizeissue++; }

                                    if(c=='!'&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                                    if(c=='!'&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }
                                    if(c=='!'&&(l==0)&&issuethree>0) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }

                                    if(c=='.'&&(u==0)) {chtype--;u=1; issuethree--; if(sizeissue<0) sizeissue++; }
                                    if(c=='.'&&(d==0)&&issuethree>0) {chtype--;d=1;issuethree--; if(sizeissue<0) sizeissue++; }
                                    if(c=='.'&&(l==0)&&issuethree>0) {chtype--;l=1;issuethree--; if(sizeissue<0) sizeissue++; }

                                }

                            }
                            else i++;

                        }
                    }

                }

        //add all other changes remaining to be done
        output=output+chtype+abs(sizeissue);

        return output;

    }

    }

   };
const strongPasswordChecker = (passwd) => {
    let steps = 0;
    let mustAdd = 0;

    if (!passwd.match(/[A-Z]/)) {
        mustAdd++;
    }
    if (!passwd.match(/[a-z]/)) {
        mustAdd++;
    }
    if (!passwd.match(/\d/)) {
        mustAdd++;
    }

    let groups = passwd.match(/(.)\1*/g).filter(x => x.length > 2);

    if (passwd.length <= 20) {
        groups.forEach(group => {
            steps += Math.trunc(group.length / 3);
            mustAdd -= Math.trunc(group.length / 3);
        })
    }

    if (passwd.length <= 20) {
        mustAdd = mustAdd > 0 ? mustAdd : 0;
        if (passwd.length + steps >= 6) {
            steps += mustAdd;
        } else {
            if (mustAdd > 6 - (passwd.length + steps)) {
                steps += mustAdd;
            } else {
                steps += 6 - (passwd.length + steps);
            }
        }
    }

    if (passwd.length > 20) {
        let mustRemove = passwd.length - 20;
        let lengths = [];
        let plus = [];
        let chL = 0;
        for (let i = 1; i <= 3; i++) {
            for (let k = 0; k < groups.length; k++) {
                if (plus[k] === undefined) { plus[k] = 0; }
                chL = groups[k].length - plus[k];
                if (lengths[k] === undefined) { lengths[k] = chL; }
                const rec = () => {
                    if (Math.trunc((chL - i) / 3) < Math.trunc(chL / 3) && passwd.length - steps - i >= 6 && mustRemove >= i && chL > 2 && lengths[k] - i > 0) {
                        steps += i;
                        plus[k] += i;
                        mustRemove -= i;
                        chL -= i;
                        lengths[k] -= i;
                        rec();
                    }
                }
                rec();
            }
        }
        lengths.forEach(length => {
            if (length > 2) {
                steps += Math.trunc(length / 3);
                mustAdd -= Math.trunc(length / 3);
            }
        }
        )

        mustRemove = mustRemove > 0 ? mustRemove : 0;
        mustAdd = mustAdd > 0 ? mustAdd : 0;
        steps += mustAdd + mustRemove;
    }

    return steps;
};
Strong Password Checker