29
\$\begingroup\$

Introduction

As ToonAlfrink says: "Me thinks there aren't enough easy questions on here that beginners can attempt!". So the task is very simple. Given a string, output a truthy or falsy value whether the name is official or not.

A name is "official" if it is a single title-case word, that is:

  • If the first letter is capitalized (not official: adnan)
  • If the other letters are not capitalized (not official: AdNaN)
  • If the name doesn't contain any non-alphabetic characters (not official: Adnan123, Adnan!)
  • If the name consists of just one word (not official: Adn an, Adn An)
  • If the name has more than one character (not official: A)

Rules

  • You may provide a function or a program
  • This is , so the submission with the least amount of bytes wins!
  • Note: To simplify things, names like Mary-Ann are in this challenge not official.
  • Assume that there are no leading whitespaces in the name.
  • Assume that only the printable ASCII characters (32-126) are used in the names

Test cases

Input: Adnan
Output: True

Input: adnan
Output: False

Input: AdnaN
Output: False

Input: Adnan123
Output: False

Input: Adnan Adnan
Output: False

Input: A
Output: False

Input: Mary-Ann
Output: False

Leaderboard

/* Configuration */

var QUESTION_ID = 67554; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 34388; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "http://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "http://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    else console.log(body);
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    lang = jQuery('<a>'+lang+'</a>').text();
    
    languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
    if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body { text-align: left !important}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="language-list">
  <h2>Shortest Solution by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

\$\endgroup\$
15
  • 7
    \$\begingroup\$ So my name's not official? I'd better change it then. \$\endgroup\$ Dec 23, 2015 at 23:04
  • 15
    \$\begingroup\$ @ETHproductions If we're using this logic, Lololololololololololol is an official name :) \$\endgroup\$
    – Adnan
    Dec 23, 2015 at 23:06
  • 1
    \$\begingroup\$ That doesn't really answer the question. Which is it: "you may assume the name doesn't contain accented letters", or "names with accented letters should yield False"? \$\endgroup\$
    – Lynn
    Dec 24, 2015 at 2:29
  • 1
    \$\begingroup\$ As a slightly offbeat Canadian digression, a professor I know wouldn't be happy with your "official" criteria: Robert Smith?. His name actually does have that question mark. Also, Sahaiʔa. \$\endgroup\$ Dec 26, 2015 at 7:46
  • 1
    \$\begingroup\$ @FarhanAnam Yes \$\endgroup\$
    – Adnan
    Dec 26, 2015 at 13:37

43 Answers 43

21
\$\begingroup\$

Retina, 13 bytes

^[A-Z][a-z]+$

Try it online | Test suite (The output 0 means none of the strings matched, which is expected.)

When Retina is only provided with a single line of code, it outputs the number of times the expression matched the input string, so it will output 1 (truthy) if it matches and therefore is an official name and 0 (falsy) if it's not.

Breakdown

^       The beginning of the string
[A-Z]   One uppercase letter
[a-z]+  One or more lowercase letters
$       The end of the string
\$\endgroup\$
1
  • 9
    \$\begingroup\$ Looks like we need character classes for letters. ;) \$\endgroup\$ Dec 24, 2015 at 0:21
9
\$\begingroup\$

TeaScript, 12 bytes

xO`A-Z][a-z`

Abuses the O function.

Try this online

Test Suite

Explanation

The O function makes this:

x O   `A-Z][a-z`
x.O(/^[A-Z][a-z]+$/)

Then, the O function checks if the regex matches x.


Alternatively, a TeaScript 3 answer at 7 bytes:

xO/\A\a
\$\endgroup\$
2
  • \$\begingroup\$ Ahahaha, nice one. At some point while I was working on the Japt interpreter, I used this trick with the isChar function you added. But you may want to explain in more detail for those not in the know. \$\endgroup\$ Dec 24, 2015 at 1:55
  • \$\begingroup\$ Ooooooh, I like the new regex features! \$\endgroup\$ Dec 27, 2015 at 2:06
7
\$\begingroup\$

JavaScript (ES6), 26

n=>/^[A-Z][a-z]+$/.test(n)

By: Edcsixtyfive

f=n=>/^[A-Z][a-z]+$/.test(n)

console.log=x=>O.textContent+=x+'\n'

;['Adnan','adnan','AdnaN','Adnan123','Adnan Adnan','A','Mary-Ann']
.forEach(t=>console.log(t+' '+f(t)))
<pre id=O></pre>

\$\endgroup\$
9
  • \$\begingroup\$ Darn, you beat me to it. You also outgolfed my version by 5 bytes. \$\endgroup\$ Dec 24, 2015 at 0:08
  • 1
    \$\begingroup\$ One byte less: n=>n.match`^[A-Z][a-z]+$` \$\endgroup\$
    – user81655
    Dec 24, 2015 at 4:09
  • \$\begingroup\$ @user81655 an array as a truthy value is too forced IMHO \$\endgroup\$
    – edc65
    Dec 24, 2015 at 9:16
  • \$\begingroup\$ @edc65 It is valid though. \$\endgroup\$ Dec 24, 2015 at 15:20
  • 1
    \$\begingroup\$ For only 4 bytes more you get ES5 compliance: /./.test.bind(/^[A-Z][a-z]+$/) \$\endgroup\$
    – CR Drost
    Dec 24, 2015 at 17:26
7
\$\begingroup\$

Python, 59 58 bytes

I'm sure there's no real way to beat the Retina version, since this is basically just that within Python. But I think this is my first submission ;)

import re,sys;print(re.match('[A-Z][a-z]+$',sys.argv[1]))

It's a very odd truthy value:

(test2)wayne@arglefraster ~/programming/inactive/golf/67554
⚘ python golf.py AdNan                                                                                                 $? 148  %# 3  10:06:36
None
(test2)wayne@arglefraster ~/programming/inactive/golf/67554
⚘ python golf.py Adnan                                                                                                         %# 3  10:06:40
<_sre.SRE_Match object at 0x7feefea7f440>
(test2)wayne@arglefraster ~/programming/inactive/golf/67554
⚘ python golf.py "Adnan Banana"                                                                                                %# 3  10:06:47
None

(And it does require "" around strings with spaces in it, if passed via the shell)

\$\endgroup\$
7
  • 1
    \$\begingroup\$ ^ is not needed as re.match() only matches at the beginning of string. \$\endgroup\$
    – manatwork
    Dec 24, 2015 at 16:20
  • 1
    \$\begingroup\$ @manatwork nice! Another byte shaved :) I could save another byte with the closing paren, using Python2 \$\endgroup\$ Dec 24, 2015 at 16:32
  • 1
    \$\begingroup\$ @WayneWerner: that's why you should give the Python version :) I think Python 2 and Python 3 are kind of different languages, at least for codegolf. \$\endgroup\$
    – movatica
    May 23, 2019 at 20:01
  • \$\begingroup\$ If you use a anonymous lambda instead of a whole program, you get 45 bytes: lambda s:re.match('[A-Z][a-z]+$',s) import re \$\endgroup\$
    – movatica
    May 23, 2019 at 20:25
  • 1
    \$\begingroup\$ @movatica Oh, whoops! \$\endgroup\$
    – MilkyWay90
    Jun 15, 2019 at 22:01
6
\$\begingroup\$

Pyth, 16 13 12 bytes

Thanks to @Thomas Kwa for reminding me about titlecase.

&qzr@GrzZ3tz

Test Suite.

&              Boolean and operator
 qz            Equality test on input
  r    3       Titlecase operator
   @G          Setwise intersection with the alphabet
    rzZ        Input to lowercase
 tz            All but the first character of the input
\$\endgroup\$
0
4
\$\begingroup\$

Java, 53 bytes

boolean b(String a){return a.matches("[A-Z][a-z]+");}
\$\endgroup\$
1
  • \$\begingroup\$ You can use a lambda: s->s.matches("[A-Z][a-z]+") \$\endgroup\$ May 17, 2019 at 14:58
4
\$\begingroup\$

Python, 50 45 43 41 bytes

lambda s:s.isalpha()*s.istitle()*len(s)>1

Returns True if it's an official name or False if it's not.

\$\endgroup\$
1
  • \$\begingroup\$ Rules of codegolf state, that you don't need to take the f= into account, saving two bytes. Also, (len(s)>1) saves 5 bytes over s[1:].islower(). :) \$\endgroup\$
    – movatica
    May 23, 2019 at 20:24
3
\$\begingroup\$

BotEngine, 203 180 29x6=174

v ABCDEFGHIJKLMNOPQRSTUVWXYZ
>ISSSSSSSSSSSSSSSSSSSSSSSSSSF
v <<<<<<<<<<<<<<<<<<<<<<<<<<
 Tabcdefghijklmnopqrstuvwxyz
> SSSSSSSSSSSSSSSSSSSSSSSSSSF
^E<<<<<<<<<<<<<<<<<<<<<<<<<<

I should really add builtins for identifying uppercase and lowercase letters. That would be much more concise than checking each letter individually.

Rough translation:

for a of input enqueue a
if ABCDEFGHIJKLMNOPQRSTUVWXYZ contains first
 remove first
 while abcdefghijklmnopqrstuvwxyz contains first
  remove first
 if empty
  yield TRUE exit
 else
  yield FALSE exit
else
 yield FALSE exit
\$\endgroup\$
3
\$\begingroup\$

Ruby, 28 bytes

p (gets=~/^[A-Z][a-z]+$/)!=p

-2 bytes( thanks to manatwork )

\$\endgroup\$
3
3
\$\begingroup\$

C, 129 122 121 111 bytes

main(c,b,d){b=d=0;while((c=getchar())>13)b|=b|=!b&&c>90|c<65?1:2&&d++&&c<97|c>122?4:2;printf("%d\n",b<3&&d>1);}

Try It Online

main(c,b,d)
{
    b=d=0;
    while((c=getchar())>13)
    {
        // Twiddle bits, 1<<0 for first character and 1<<3 for subsequent
        b|=!b&&c>90|c<65?1:2; // check first character is valid
        b|=d++&&c<97|c>122?4:2; // check later characters are valid
    }
    // If all OK b == 2, if either of above are wrong, b >= 3 due to 
    // extra bits. Also, d should be > 1 for name length to be valid.
    printf("%d\n",b<3&&d>1);
}
\$\endgroup\$
3
\$\begingroup\$

VB6, 48 bytes

Function f(i):f=i Like"[A-Z][a-z]+":End Function
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 11 7 6 bytes

á™QצĀ

-4 bytes thanks to @Grimy.

Try it online or verify all test cases.

Explanation:

á       # Only leave the letters of the (implicit) input
        #  i.e. "Adnan" → "Adnan"
        #  i.e. "A" → "A"
        #  i.e. "aDNAN" → "aDNAN"
        #  i.e. "Adnan123" → "Adnan"
 ™      # Titlecase it
        #  i.e. "Adnan" → "Adnan"
        #  i.e. "Adnan" → "A"
        #  i.e. "aDNAN" → "Adnan"
  Q     # Check if it's still equal to the (implicit) input
        #  i.e. "Adnan" and "Adnan" → 1 (truthy)
        #  i.e. "A" and "A" → 1 (truthy)
        #  i.e. "aDNAN" and "Adnan" → 0 (falsey)
        #  i.e. "Adnan123" and "Adnan" → 0 (falsey)
   ×    # Repeat the (implicit) input that many times
        #  i.e. "Adnan" and 1 → "Adnan"
        #  i.e. "A" and 1  → "A"
        #  i.e. "aDNAN" and 0 → ""
        #  i.e. "Adnan123" and 0 → ""
    ¦Ā  # Remove the first character, and check that it's non-empty
        #  i.e. "Adnan" → "dnan" → 1 (truthy)
        #  i.e. "A" → "" → 0 (falsey)
        #  i.e. "" → "" → 0 (falsey)
        # (which is output implicitly as result)
\$\endgroup\$
2
  • 1
    \$\begingroup\$ 7 bytes: á™Qиg2@ \$\endgroup\$
    – Grimmy
    May 17, 2019 at 13:52
  • 1
    \$\begingroup\$ @Grimy Thanks, but the и should be × instead. By using и you create a list with the string in it, so the length of that list is always 1 regardless of the string length. \$\endgroup\$ May 17, 2019 at 14:12
2
\$\begingroup\$

MATL, 18 bytes

The current version (4.0.0) of the language is used.

This applies the same regular expression as NinjaBearMonkey's answer:

j'^[A-Z][a-z]+$'XX

The output is the string (which is truthy) if it's an official name, and nothing (which is falsy) if it's not.

Examples

>> matl
 > j'^[A-Z][a-z]+$'XX
 > 
> December
December
>> 

>> matl
 > j'^[A-Z][a-z]+$'XX
 > 
> ASCII
>> 
\$\endgroup\$
2
\$\begingroup\$

Haskell, 61 bytes

f(h:t@(_:_))=elem h['A'..'Z']&&all(`elem`['a'..'z'])t
f _=1<0
\$\endgroup\$
2
  • \$\begingroup\$ One byte fewer \$\endgroup\$
    – dfeuer
    Jun 20, 2019 at 5:02
  • \$\begingroup\$ Several more down. You could also use that technique for the other test to be more efficient, but it's the same number of bytes. \$\endgroup\$
    – dfeuer
    Jun 20, 2019 at 5:08
2
\$\begingroup\$

Gema, 17 characters

\B<K1><J>\E=1
*=0

Sample run:

bash-4.3$ echo -n 'Adnan' | gema '\B<K1><J>\E=1;*=0'
1

bash-4.3$ echo -n 'adnan' | gema '\B<K1><J>\E=1;*=0'
0

bash-4.3$ echo -n 'Adnan123' | gema '\B<K1><J>\E=1;*=0'
0
\$\endgroup\$
2
\$\begingroup\$

IA-32 machine code, 19 bytes

A function that receives the pointer to a null-terminating string in ecx and returns 0 or 1 in eax (according to the fastcall convention).

Hexdump of the code:

6a 20 58 32 01 74 0a 41 2c 61 3c 1a b0 00 72 f3 c3 40 c3

In assembly language:

    push 32;
    pop eax;

myloop:
    xor al, [ecx];
    jz yes;
    inc ecx;
    sub al, 'a';
    cmp al, 26;
    mov al, 0;
    jb myloop;
    ret;

yes:
    inc eax;
    ret;

The first byte of the input name has its 5th bit flipped (xor with 32) to convert it from capital case to small case. This loads 32 into eax, using 3 bytes of code:

    push 32;
    pop eax;

To check whether the byte is a small letter:

    sub al, 'a';
    cmp al, 26;
    jb myloop;

If not, this code falls through. To return 0 in this case, it puts 0 in al before doing the conditional jump:

    sub al, 'a';
    cmp al, 26;
    mov al, 0;
    jb myloop;

The 0 in al also serves as a xor-mask (or absence of it) for the following bytes of the input name.

A successful exit is when it encounters a zero byte, which stays zero after the xor:

    xor al, [ecx];
    jz yes;

It assumes that the input name is not empty. I guess it's a reasonable assumption about a name (not an arbitrary string)!

\$\endgroup\$
2
\$\begingroup\$

grep, 16 bytes

This is the pattern:

[A-Z][a-z]+

If you use the -E and -x and -c switches grep will print a count of matching input lines. So if you give it one line you get a 1 or a 0. I think that's how this place works.

The pattern is 11 chars, the whole command line is 23. I've seen people use sed scripts without the command so I don't know what is what. But, it reads stdin, and so you can just type at it. Here's echo:

for a in Adnan adnan Ad\ nan
do  echo "$a" | grep -cxE \[A-Z]\[a-z]+
done

1
0
0
\$\endgroup\$
4
  • \$\begingroup\$ @Doorknob - seems fair enough to me. thanks very much. which hat did you guess? \$\endgroup\$
    – mikeserv
    Dec 25, 2015 at 14:38
  • 1
    \$\begingroup\$ I figured out Hairboat's Revenge. :P \$\endgroup\$
    – Doorknob
    Dec 25, 2015 at 14:42
  • \$\begingroup\$ Stop me if (as is quite probable) I'm wrong but you can use grep -Exc so you don't need to count as many bytes for the switches. \$\endgroup\$
    – Neil
    Dec 25, 2015 at 19:41
  • \$\begingroup\$ @Neil - i dunno if you're wrong. i have really no idea - have a look at the edit history. \$\endgroup\$
    – mikeserv
    Dec 25, 2015 at 20:02
2
\$\begingroup\$

Mathematica 10.1, 46 bytes

LetterQ@#&&#==ToCamelCase@#&&StringLength@#>1&

Uses one less byte than the standard regex solution. It does three checks. LetterQ@# ensures that the string is entirely composed of letters, and StringLength@#>1 invalidates single-letter strings. #==ToCamelCase@# makes less sense, however. ToCamelCase is an undocumented function I found that takes an input string AndOutputsItLikeThis. Since there is only one word, it will capitalize the first letter, so we check if the string is equal to that.

\$\endgroup\$
3
  • \$\begingroup\$ Is ToCamelCase new in 10.3? Doesn't seem to work in 10.2. \$\endgroup\$
    – murphy
    Dec 25, 2015 at 16:20
  • \$\begingroup\$ @murphy, it works for me in 10.1. What do you get with ToCamelCase["foo bar baz"]? \$\endgroup\$ Dec 25, 2015 at 16:31
  • \$\begingroup\$ Ok, I can confirm that it works in 10.1. However, in 8.0, 9.0, 10.0 and 10.2 the function is not defined (your test case returns ToCamelCase[foo bar baz]). Strange! Maybe someone can check 10.3? \$\endgroup\$
    – murphy
    Dec 25, 2015 at 21:56
2
\$\begingroup\$

bash/zsh/ksh, 25 bytes

[[ $1 =~ ^[A-Z][a-z]+$ ]]

To actually use this, make a file with it as the only line and make the file executable; executable files not recognized as a known binary type are treated as shell scripts (for /bin/sh specifically).

$ printf '[[ $1 =~ ^[A-Z][a-z]+$ ]]' >f
$ chmod +x f
$ wc -c f
25 f
$ for x in 'Adnan' 'adnan' 'AdnaN' 'Adnan123' 'Adnan Adnan' 'A' 'Mary-Ann'; do f "$x" && echo 1 || echo 0; done
1
0
0
0
0
0
0
$ 
\$\endgroup\$
3
  • 2
    \$\begingroup\$ This works fine in bash, ksh and zsh, but has no chance to work in standard POSIX sh or the compatible dash and yash. To avoid confusion, I suggest to change the answer's title. \$\endgroup\$
    – manatwork
    Dec 24, 2015 at 9:57
  • 3
    \$\begingroup\$ Use printf instead of echo to create the file and you’ll get 25 bytes. \$\endgroup\$ Dec 24, 2015 at 15:21
  • \$\begingroup\$ Good points, both of you; both applied. \$\endgroup\$ Dec 28, 2015 at 17:10
2
\$\begingroup\$

C# 4, 89 bytes

My first attempt at Code Golf. Here it comes:

bool o(string i){return System.Text.RegularExpressions.Regex.IsMatch(i,"^[A-Z][a-z]+$");}

See it in action at Dot Net Fiddle.

\$\endgroup\$
1
  • \$\begingroup\$ If you use C# 6, you can make it a bit shorter: bool o(string i)=>System.Text.RegularExpressions.Regex.IsMatch(i,"^[A-Z][a-z]+$"); \$\endgroup\$
    – ProgramFOX
    Dec 26, 2015 at 14:01
2
\$\begingroup\$

Java, 28 bytes

n->n.matches("[A-Z][a-z]+")

Uses regex to make sure the string consists of an uppercase character followed by at least one lowercase character.

-1 bytes thanks to Benjamin Urquhart

\$\endgroup\$
2
  • \$\begingroup\$ You can drop the semicolon \$\endgroup\$ May 17, 2019 at 15:00
  • \$\begingroup\$ @BenjaminUrquhart oh right, thanks \$\endgroup\$
    – hyper-neutrino
    May 18, 2019 at 17:45
2
\$\begingroup\$

Vyxal, 8 bytes

Lċ?₍ǐǍ≈∧

Try it Online (with test cases)!

Potentially golfable. I swear there was a builtin for len(a)>1...

Assumes input is nonempty.

L        # Length of input
 ċ       # is not 1
  ?      # Push the input,
   ₍     # parallel apply...
    ǐ    # title case and
     Ǎ   # keep only alphabetic chars
      ≈  # is equal?
       ∧ # bitwise AND the length and ^
\$\endgroup\$
1
  • \$\begingroup\$ 6 bytes (port of Kevin Cruijssen's 05AB1E answer) \$\endgroup\$
    – The Thonnu
    Apr 27, 2023 at 9:43
2
\$\begingroup\$

Thunno 2 b, 5 bytes

Ịḟ=×ḣ

Port of Kevin Cruijssen's 05AB1E answer.

Explanation

Ịḟ=×ḣ  # Implicit input
Ị      # Remove non-alphabets from the input
 ḟ     # Convert this string to title case
  =    # Check whether it's still equal to the input
   ×   # Repeat the input this many times
       # (i.e. input if true, empty string otherwise)
    ḣ  # Remove the first character from this string
       # The b flag boolifies the resulting string,
       # checking that it is not empty
       # Implicit output

Screenshots

Screenshot 1 Screenshot 2

(click to enlarge)

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

k4, 39 bytes

{((*x)in .Q.A)&(&/(1_,/x)in .Q.a)&1<#x}

First char is upper, all others are lower, count greater than one.

E.g.:

  {((*x)in .Q.A)&(&/(1_,/x)in .Q.a)&1<#x}'("Adnan";"adnan";"AdnaN";"Adnan123";"Adnan Adnan";"A";"Mary-Ann")
1000000b
\$\endgroup\$
1
\$\begingroup\$

Seriously, 16 bytes

ú4,nÿ=)l1<)ù-Y&&

Hex Dump:

a3342c6e983d296c313c29972d592626

Try It Online

Seriously does not have regex support yet, so the best we can do is:

 4,n                               Push 4 copies of input
    ÿ=                             Check that it's equal to itself converted to titlecase
      )                            Put the boolean on the bottom
       l1<                         Check that it's longer than 1 character
          )                        Put the boolean on the bottom
           ù                       Convert it to lowercase.
ú           -Y                     Check that removing the lowercase alphabet empties it
              &&                   And all the booleans together
\$\endgroup\$
1
\$\begingroup\$

Ocaml, 231 216 197 166 bytes

let f n=let l=String.length n in if l=1 then 0 else let rec e=function 0->1|i->match n.[i] with('a'..'z')->e(i - 1)|_->0 in match n.[0]with('A'..'Z')->e(l - 1)|_->0;;

Example usage:

# f "Adnan";;
- : int = 1

# f "adnan";;
- : int = 0

# f "AdnaN";;
- : int = 0

# f "Adnan123";;
- : int = 0

# f "Adnan Adnan";;
- : int = 0

# f "A";;
- : int = 0

# f "Mary-Ann";;
- : int = 0

Ungolfed (with real function names):

let is_name name =
  let len = String.length name
  in if len = 1 then 0 else
  let rec explode_lower = function
    | 0 -> 1
    | i ->
      match name.[i] with
      | ('a'..'z') -> explode_lower (i - 1)
      | _ -> 0
  in match name.[0] with
  | ('A'..'Z') -> explode_lower (len - 1)
  | _ -> 0;;
\$\endgroup\$
1
  • \$\begingroup\$ You could actually save about 10% by using booleans instead of integers (bleh!) and replacing those bulky if … then 0 else by … ||. And for that matter by using boolean operators instead of match and ranges, e.g. n.[0]>'@'&n.[0]<'['&e(l-1) \$\endgroup\$ Dec 26, 2015 at 19:29
1
\$\begingroup\$

SpecBAS - 39 bytes

SpecBAS handles regular expressions through the MATCH command. Output is 0 for false and 1 if true.

1 input n$:  ?MATCH("^[A-Z][a-z]+$",n$)
\$\endgroup\$
1
\$\begingroup\$

Swift 2, 116 bytes

Regex is so verbose in Swift that doing this is much shorter

func e(s:String)->Int{var c=0;for k in s.utf8{if(c==0 ?k<65||k>90:k<97||k>122){return 0};c++};return s.utf8.count-1}

This will return 0 or -1 (in the case of no input) for non-official names, and a number > 0 (which is equal to the length of the string - 1) if the name is official

Ungolfed

func e(s: String) -> Int{
    var c = 0
    for k in s.utf8{
        if(c == 0 ? k < 65 || k > 90 : k < 97 || k > 122){
            return 0
        }
        c++
    }
    return s.utf8.count - 1
}
\$\endgroup\$
1
\$\begingroup\$

C#, 188 bytes

Regular expressions would have been the right way to tackle this, but here's an attempt without it.

bool O(string s){for(int i=1;i<s.Length;i++){if(char.IsUpper(s[i])){return false;}}if(char.IsUpper(s[0])&&s.All(Char.IsLetter)&&!s.Contains(" ")&& s.Length > 1){return true;}return false;}

Longhand

static bool O(string s)
{
    for (int i = 1; i < s.Length; i++)
    {
        if (char.IsUpper(s[i]) )
        {
            return false;
        }
    }
    if (char.IsUpper(s[0]) && s.All(Char.IsLetter) && !s.Contains(" ") && s.Length > 1)
    {
        return true;
    }
    return false;
}

Would love advice on how to make the lowercase check shorter, perhaps without the loop. I just started learning the language, and used this as practice, figured I'd share my result anyway.

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

Perl 5 -p, 18 bytes

$_=/^[A-Z][a-z]+$/

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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