Strong Password¶
JavaScript¶
Solution 1¶
The solution is \(max(6 - n, 4 - d)\) where n
is string length and d
is the number of different type of characters that are already present in the input password.
/**
* A password must contain at least 6 characters.
*/
const MIN_LEN = 6;
/**
* A password must contain at least 1 char from each of the four
* character classes blow.
*/
const NUMS = '0123456789';
const LOWERS = 'abcdefghijklmnopqrstuvwxyz';
const UPPERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const SPECIALS = '!@#$%^&*()-+';
/**
* Checks if `str` contains a char from `oneOf`.
*
* - T.C: O(n²).
* - S.C: O(n).
*
* @sig String -> String -> Boolean
* @param {string} str
* @param {string} oneOf
* @returns {boolean}
*/
function contains(str, oneOf) {
return !![...oneOf].find(c => str.includes(c));
}
/**
* Returns the number of missing chars required to satisfy the
* password requirements.
*
* - T.C: O(n²) because of `contains()`, which is itself O(n²).
* - S.C: O(1).
*
* @param {number} length The length of the input password string.
* @param {string} password The password string.
* @returns {number} The number of missing chars.
*/
function minNum(length, password) {
const missingLength = MIN_LEN - length;
let missingType = 4;
if (contains(password, NUMS))
missingType -= 1;
if (contains(password, LOWERS))
missingType -= 1;
if (contains(password, UPPERS))
missingType -= 1;
if (contains(password, SPECIALS))
missingType -= 1;
return Math.max(missingLength, missingType);
}
Solution 2¶
/**
* A password must contain at least 6 characters.
*/
const MIN_LEN = 6;
/**
* A password must contain at least 1 char from each of the
* four character classes blow.
*/
const NUMS = '0123456789';
const LOWERS = 'abcdefghijklmnopqrstuvwxyz';
const UPPERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const SPECIALS = '!@#$%^&*()-+';
/**
* Checks if `str` contains a char from `oneOf`.
*
* - T.C: O(n²).
* - S.C: O(n).
*
* @sig String -> String -> Boolean
* @param {string} str
* @param {string} oneOf
* @returns {boolean}
*/
function contains(str, oneOf) {
return !![...oneOf].find(c => str.includes(c));
}
/**
* Returns the number of missing chars required to satisfy the
* password requirements.
*
* - T.C: O(n³).
* - S.C: O(1).
*
* @sig Number -> String -> Number
* @param {number} length The length of the input password string.
* @param {string} password The password string.
* @returns {number} The number of missing chars.
*/
function minNum(length, password) {
const missingLength = MIN_LEN - length;
const charClasses = [NUMS, LOWERS, UPPERS, SPECIALS];
const missingType = charClasses.reduce((count, charClass) => {
return contains(password, charClass) ? count - 1 : count;
}, charClasses.length);
return Math.max(missingLength, missingType);
}
Here charClasses.length
is used as reduce’s accumulator.
Each time a character class is found in password
, 1 is reduced from that accumulator (count
inside the reducer callback), 1 is subtracted.
In the end, the max of missingLength
or missingType
is returned to satisfy the challenge requirements.
Finally, the time complexity is \(O(n³)\) because we use contains()
(which is $O(n²)) inside reduce()
.