8
\$\begingroup\$

Introduction

In Android Studio and other IDEs there are code completions to assist efficient code insertion (especially when the names of the classes or methods are so verbose), like the one in the image below.

enter image description here

There are slightly different logics used between IDEs to determine what classes, methods and variables to suggest, but otherwise are common: typing the initial letters of each word, and the identifier matching those initial letters will be suggested.

Challenge

In this challenge, write a program or function which receives two strings, namely input and identifier, determine whether the identifier matches the input.

We split identifier into words where:

  • a lowercase letter is followed by an uppercase letter ("SplitHere" -> "Split", "Here"),
  • an uppercase letter is followed by an uppercase letter and a lowercase letter ("SPLITHere" -> "SPLIT", "Here"), or
  • there is a number or an underscore _ ("SPLIT_HERE" -> "SPLIT", "HERE").

If this is still not clear enough, here is the regex representing the condition to split: (?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|[_0-9]. Here are a few samples:

  • theWord_Example, in which 3 words (the, Word, Example) can be found.
  • THEWORD2EXAMPLE, in which only 2 words (THEWORD, EXAMPLE) can be found (because THEWORD is a run of uppercase letters and so does EXAMPLE).
  • THEWordEXAMPLE3, in which 3 words (THE, Word, Example) can be found (Word is considered to be a separate word here).
  • THEWORDEXAMPLEFOUR, in which only 1 words (THEWORDEXAMPLEFOUR) can be found (the whole run of uppercase letters).

For this purpose here we use a simplified version. In reality the logic is far more complex. In this version there are only two rules:

  1. If input consists of only lowercase letters, then an identifier matches the input only if there is a splitting of input into substrings, that for each substring there is a word within the identifier starting with that substring, in that exact order.

    Example input: sbo

    Truthy cases: SQLiteBindOrColumnIndexOutOfRangeException, SparseBooleanArray, (UPDATE) StringIndexOutOfBoundException

    Falsy cases: SeekBar (missing o), StatusBarNotification (the o is not at the beginning of a word)

  2. If input contains uppercase letters, then a split on the input must be made before each uppercase letter when applying Rule 1.

    Example input: sbO

    Truthy cases: SQLiteBindOrColumnIndexOutOfRangeException

    Falsy cases: SparseBooleanArray (the O must appear at the beginning of a word), StringIndexOutOfBoundException (wrong order)

I/O

Input: two strings, one for input and one for identifier. You can assume that the regex [A-Za-z]+ matches input and the regex [A-Za-z0-9_] matches identifier.

Output: one of the truthy or falsy values. You can choose what value to return as truthy and what as falsy, but your choice must be consistent across all cases. For example you can return 1/0, true/false, π/e or whatever, but they must stay the same across all cases.

Test cases

Each line consists of two strings, namely input and identifier respectively.

Truthy cases:

"sbo" "SparseBooleanArray"
"sbo" "StringIndexOutOfBoundException"
"sbo" "SQLiteBindOrColumnIndexOutOfRangeException"
"sbO" "SQLiteBindOrColumnIndexOutOfRangeException"
"Al" "ArrayList"
"AL" "ArrayList"
"Al" "ALARM_SERVICE"
"As" "ALARM_SERVICE"
"AS" "ALARM_SERVICE"
"SD" "SQLData"
"SqD" "SQLData"
"SqlD" "SQLData"
"SqDa" "SQLData"
"the" "theWord_Example"
"the" "THEWORD2EXAMPLE"
"the" "THEWordEXAMPLE3"
"the" "THEWORDEXAMPLEFOUR"
"thw" "theWord_Example"
"thw" "THEWordEXAMPLE3"
"te" "theWord_Example"
"te" "THEWORD2EXAMPLE"
"te" "THEWordEXAMPLE3"

Falsy cases:

"sbo" "SeekBar"
"sbo" "StatusBarNotification"
"sbO" "StringIndexOutOfBoundException"
"sbO" "SparseBooleanArray"
"AL" "ALARM_SERVICE"
"ASE" "ALARM_SERVICE"
"SQD" "SQLData"
"SqLD" "SQLData"
"SLD" "SQLData"
"SQDt" "SQLData"
"SQDA" "SQLData"
"thw" "THEWORD2EXAMPLE"
"thw" "THEWORDEXAMPLEFOUR"
"te" "THEWORDEXAMPLEFOUR"

Winning Criteria

This is a , so shortest code of each language wins. Default loopholes are not allowed.

\$\endgroup\$
  • 1
    \$\begingroup\$ so "SQLData", "SQLData" is false? \$\endgroup\$ – l4m2 Nov 12 '18 at 1:21
  • \$\begingroup\$ @l4m2 Yes as per the simplified rules. However "sqldata", "SQLData" is true. \$\endgroup\$ – Shieru Asakoto Nov 12 '18 at 1:24
  • 1
    \$\begingroup\$ can "sbo" "StringIndexOutOfBoundException"match *S*tringIndexOutOf*Bo*undException ? \$\endgroup\$ – TFeld Nov 12 '18 at 9:44
  • \$\begingroup\$ @TFeld Oh I made a mistake on the cases, thanks for reminding \$\endgroup\$ – Shieru Asakoto Nov 12 '18 at 11:05
1
\$\begingroup\$

Python 2, 239 227 bytes

lambda a,b:any(re.match(w,''.join(map(str.title,re.sub('(?=[A-Z][a-z])|(?<=[a-z])(?=[A-Z])|(\d)','_',b).split('_'))))for w in g(a))
import re
g=lambda s:s and{c+w for w in g(s[1:])for c in[s[0],'.*'+s[0].upper()][s<'[':]}or{''}

Try it online!

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

JavaScript (ES6), 177 bytes

Expects (identifier)(input).

S=>g=([c,...s],l=[],o='')=>c?g(s,o?[...l,o]:l,c)|c>{}&g(s,l,o+c):eval(`/~${[...l,o].join`.*~`}/i`).test(S.replace(/./g,(c,i)=>!i|(!/[A-Z]/.test(l)|S[i+1]>'_')&(l=c)<{}?'~'+c:c))

Try it online!

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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