This is a Leetcode problem –

A password is considered strong if below conditions are all met –

1.It has at least 6 characters and at most 20 characters.

2.It must contain at least one lowercase letter, at least one uppercase letter, and at least one digit.

3.It mustNOTcontain three repeating characters in a row (`...aaa...`

is weak, but`...aa...a...`

is strong, assuming other conditions are met).

Write a function`strong_password_checker(s)`

, that takes a string`s`

as input, and returns theMINIMUMchange required to make`s`

a strong password. If`s`

is already strong, return`0`

.

Insertion, deletion or replacements of any one character are all considered as one change.

Here is my solution to this challenge –

`def strong_password_checker(s: str) -> int: def has_lower(s): for c in s: if c.islower(): return 1 return 0 def has_upper(s): for c in s: if c.isupper(): return 1 return 0 def has_digits(s): for c in s: if c.isnumeric(): return 1 return 0 def find_repeats(s): i = 0 j = 0 repeats = [] while i < len(s) - 1: if s[i+1] == s[i]: i += 1 continue if (i - j + 1) > 2: repeats.append(i - j + 1) i += 1 j = i if (i - j + 1) > 2: repeats.append(i - j + 1) return repeats def repeats_after_delete(reps, d): if d >= sum([r - 2 for r in reps]): return [] reps = sorted(reps, key=lambda d: d%3) while d > 0: for i in range(len(reps)): if reps[i] < 3: continue r = reps[i] % 3 + 1 reps[i] -= min(r, d) d -= r if d <= 0: break return [r for r in reps if r > 2] def num_repeats_change(repeats): return sum([r // 3 for r in repeats]) total_changes = 0 format_changes = (1 - has_lower(s)) + (1 - has_upper(s)) + (1 - has_digits(s)) repeats = find_repeats(s) if len(s) < 6: repeat_change = num_repeats_change(repeats) total_changes = max([6 - len(s), format_changes, repeat_change]) elif len(s) > 20: repeats = repeats_after_delete(repeats, len(s) - 20) repeat_change = num_repeats_change(repeats) total_changes = len(s) - 20 + max([repeat_change, format_changes]) else: repeat_change = num_repeats_change(repeats) total_changes = max([repeat_change, format_changes]) return total_changes`

Here are some example outputs –

`#print(strongPasswordChecker("aaaaaaaaaaaaAsaxqwd1aaa")) >>> 6 #Explanation - aa1aa1aa1aAsaxqwd1aa (just an example - delete three characters, add three digits to replace consecutive a's) `

`#print(strongPasswordChecker("aaaaa")) >>> 2 #Explanation - aaAaa1 (just an example - add a character (so the length is at least 6), add an uppercase letter to replace consecutive a's) `

`#print(strongPasswordChecker("aAsaxqwd2aa")) >>> 0 #Explanation - A strong password (all conditions are met) `

Here are the times taken for each output –

`%timeit strongPasswordChecker("aaaaaaaaaaaaAsaxqwd1aaa") >>> 18.7 µs ± 1.75 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each) %timeit strongPasswordChecker("aaaaa") >>> 5.05 µs ± 594 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) %timeit strongPasswordChecker("aAsaxqwd2aa") >>> 7.19 µs ± 469 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) `

So, I would like to know whether I could make this program shorter and more efficient.

Any help would be highly appreciated.