4
\$\begingroup\$

The shortest reliable password testing code

Introduction

I started playing Empire of Code recently, and there was some challenge. The player is supposed to write a piece of Python or Javascript code to detect if the string passed to it is reliable password, that is, it contains at least one lowercase Latin letter, one uppercase Latin letter and one digit and has at least 10 characters.

It was quite easy for me to fit within the 130 characters limit for rank 3 using Javascript, however, I spent a lot of time trying to fit within the 100 characters limit for rank 3 using Python. Some guy said that he has managed to fit in 71 characters for Python. I tried hard but still couldn't reduce the code to less than 90 characters. Is it possible to use even less than 71 characters?

Winning condition: The shortest Python code (or Javascript), which solves given problem, wins. You may assume whatever was assumed in the original problem description in the game, given below.

Remark: The solution should define a function or method called "golf" which takes the password as the first parameter and returns a boolean value indicating whether the given password satisfies the criterion.

Challenge Vault Password
[The following description is merged from two versions of the problem description (for Python and for Javascript), copied from the game site https://empireofcode.com/ ]

We've installed a new vault to contain our valuable resources and treasures, but before we can put anything into it, we need a suitable password for our new vault. One that should be as safe as possible.

The password will be considered strong enough if its length is greater than or equal to 10 characters, it contains at least one digit, as well as at least one uppercase letter and one lowercase letter. The password may only contain ASCII latin letters or digits, no punctuation symbols.

You are given a password. We need your code to verify if it meets the conditions for a secure password.

In this mission the main goal to make your code as short as possible. The shorter your code, the more points you earn. Your score for this mission is dynamic and directly related to the length of your code.

Input: A password as a string.

Output: A determination if the password safe or not as a boolean, or any data type that can be converted and processed as a boolean. When the results process, you will see the converted results.

Example:

golf('A1213pokl') === false

golf('bAse730onE') === true

golf('asasasasasasasaas') === false

golf('QWERTYqwerty') === false

golf('123456123456') === false

golf('QwErTy911poqqqq') === true

Precondition:

0 < |password| ≤ 64

The password matches the regexp expression "[a-zA-Z0-9]+"

Scoring:

Scoring in this mission is based on the number of characters used in your code (comment lines are not counted).

Rank1:

Any code length.

Rank2:

Your code should be shorter than 230 characters for Javascript code or shorter than 200 characters for Python code.

Rank3:

Your code should be shorter than 130 characters for Javascript code or shorter than 100 characters for Python code.

\$\endgroup\$
6
\$\begingroup\$

Python, 59 bytes

golf=lambda s:(9<len(s))*(s.lower()>s>s.upper())*'?'>min(s)

(Still) probably not optimal.

\$\endgroup\$
  • 1
    \$\begingroup\$ I think the first part can just be (min(s)<'A')*. \$\endgroup\$ – xnor Sep 28 '15 at 13:36
  • 1
    \$\begingroup\$ I think you can use > instead of !=. \$\endgroup\$ – Maltysen Sep 28 '15 at 14:05
  • \$\begingroup\$ Both versions work. Can anyone explain why this work? golf=lambda s:(min(s)<'A')*(s.lower()!=s!=s.upper())*(9<len(s)) ok! Got it! If we convert string to lowercase and there are uppercase characters, string wouldn't match itself, and if we convert string to uppercase which has lowercase characters, it wouldn't match itself. \$\endgroup\$ – Patlatus Sep 28 '15 at 14:06
  • \$\begingroup\$ Thanks @xnor and @Maltysen. I have shaved off 10 bytes now.` \$\endgroup\$ – Tryth Sep 29 '15 at 4:41
1
\$\begingroup\$

JavaScript ES6, 67 - ES5, 88

Slightly longer than necessary as it has to return a proper true/false value (not truthy/falsy)

// MORE COMMON JAVASCRIPT - ECMASCRIPT 5 - 88 byte
function golf(p){return!(!~(p.search(/\d/)|p.search("[a-z]")|p.search("[A-Z]"))||!p[9])}

// NEWEST JAVASCRIPT - ECMASCRIPT 6 - 67 byte
/*
golf=p=>!(!~(p.search`\\d`|p.search`[a-z]`|p.search`[A-Z]`)||!p[9])
*/

// Explanation
// search gives -1 if not found, if any of search results is -1 then ORing we have a result of -1
// ~ operator is 0 if and only if operand is -1
// !p[9] is true if the string has less than 10 characters

// TEST
function out(x) {
  O.innerHTML += x + '\n'
};


;[['A1213pokl',0],['bAse730onE',1],['asasasasasasasaas',0],['QWERTYqwerty',0],['123456123456',0],['QwErTy911poqqqq',1]]
.forEach(function(pwd){out(pwd[0]+' '+!!pwd[1]+' '+golf(pwd[0]))})
<pre id=O></pre>

\$\endgroup\$
1
\$\begingroup\$

JavaScript – 83 bytes

function golf(x){return!!(/\d/.test(x)&/[a-z]/.test(x)&/[A-Z]/.test(x)&x.length>9)}
\$\endgroup\$
  • \$\begingroup\$ How about /(?=.*\d)(?=.*[a-z])(?=.[A-Z]).{10}/.test(x) \$\endgroup\$ – Martin Ender Sep 28 '15 at 21:43
  • \$\begingroup\$ function golf(x){return!!(/\d/.test(x)&/[a-z]/.test(x)&/[A-Z]/.test(x)&&x[9])} (my personal battle against the lengthy length) (+1 anyway) \$\endgroup\$ – edc65 Sep 29 '15 at 7:16
  • \$\begingroup\$ @MartinBüttner - can't get yours to work on PHP online. I think your regex skills are too advanced! \$\endgroup\$ – user15259 Sep 29 '15 at 13:45
  • \$\begingroup\$ @edc65 - I tried that, it always seems to return 0/false? \$\endgroup\$ – user15259 Sep 29 '15 at 13:45
  • \$\begingroup\$ Did you tried exaclty as I wrote it? It works! x[9] returns a 1 character string (=truthy) if the length is > 9 and an empty string (=falsy) if the length is <= 9. Must be checked with && to avoid conversion to number, as '0' converted to number is falsy. \$\endgroup\$ – edc65 Sep 29 '15 at 15:46
1
\$\begingroup\$

Python, 83 bytes

Alternatively, you can try this (93 bytes):

import re
def golf(p):
    return bool(re.findall(r'(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{10,}',p))

or (83 bytes)

import re
golf=lambda p:bool(re.findall(r'(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{10,}',p))

Try it online!

\$\endgroup\$
0
\$\begingroup\$

The solution on Python I could implement, 90 bytes

import re
golf=lambda p:re.compile(r'(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])').search(p)
\$\endgroup\$
  • \$\begingroup\$ From what I can tell, this answer doesn't check for non-alphanumeric characters which should fail the test? \$\endgroup\$ – Dendrobium Sep 28 '15 at 17:59
  • \$\begingroup\$ it checks: (?=.*\d) checks for presence of digits, (?=.*[a-z]) checks for presence of lower latin letters and (?=.*[A-Z]) checks for presence of upper latin letters. Anyway, this solution is too lengthy \$\endgroup\$ – Patlatus Sep 28 '15 at 18:02
  • \$\begingroup\$ @Dendrobium - Precondition is the password matches the regexp expression "[a-zA-Z0-9]+". \$\endgroup\$ – user15259 Sep 28 '15 at 20:48
  • 1
    \$\begingroup\$ Slightly improved regex-based solution: golf=re.compile('(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{10,}').search \$\endgroup\$ – Leo Nyx Oct 1 '15 at 6:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.