# Generate an Acronym

This is similar to Making an acronym, but there are several key differences, including the method of fetching the acronym, and this challenge including flexible output.

Given a string (list of chars/length 1 strings is allowed) containing only printable ASCII, output all capital letters in the input that are either preceded by a space or a dash, or are the first character in the input. Empty string is undefined behavior.

## Test Cases:

Output may be in the format of "TEST", ["T","E","S","T"], or whatever else works for you.

Self-contained Underwater Breathing Apparatus
SUBA

a Programming Language
PL

NATO Atlantic TREATY Organization
NATO

DEFCON 2
D

hello, world!

light-Emitting dioDe
E

What Does the Fox Say?
WDFS

3D mov-Ies
I

laugh-Out Lou-D
OLD

Best friends FOREVE-r
BF

--

<space>

--  --a -  - --

--  -- -  - -- A
A

Step-Hen@Gmail-Mail Mail.CoM m
SHMM


This is , so shortest answer in bytes wins.

• Sandbox – Stephen Jul 21 '17 at 13:21
• Can we take input as a list of Strings (list of characters)? – Mr. Xcoder Jul 21 '17 at 13:43
• @Mr.Xcoder yes. – Stephen Jul 21 '17 at 13:45
• Could you add a test case that includes some letters separated by one or more characters that aren't letters, numbers, spaces or dashes. An e-mail address, for example: My-Name@Some-Domain.TLD. – Shaggy Jul 21 '17 at 16:12
• @Shaggy added, thanks. – Stephen Jul 21 '17 at 17:10

# V, 7 bytes

ÍÕü¼À!õ


Try it online!

Here is a hexdump to prove the byte count:

00000000: cdd5 fcbc c021 f5                        .....!.


Explanation:

Í       " Search and replace all occurrences on all lines:
" (Search for)
Õ      "   A non-uppercase letter [^A-Z]
ü     "   OR
õ "   An uppercase letter
À!  "   Not preceded by...
¼    "   A word-boundary
" (implicitly) And replace it with:
"   Nothing


This is short all thanks to V's wonderful regex compression.

• That's pretty short 0.o – Stephen Jul 21 '17 at 14:57
• @StepHen Why thank you! I think this is pretty close to optimal. :) – James Jul 21 '17 at 14:58
• What do you mean by a word boundary? The question seems to suggest that only space and - are allowed. – Neil Jul 21 '17 at 15:44

# R, 66 63 bytes

function(s)(s=substr(strsplit(s,' |-')[[1]],1,1))[s%in%LETTERS]


Try it online!

-3 bytes thanks to Scarabee

An anonymous function; returns the acronym as a vector c("N","A","T","O") which is implicitly printed.

For once, this isn't too bad in R! splits on - or (space), takes the first element of each of those, and then returns whichever ones are capitals (LETTERS is an R builtin with the capital letters), in order.

• I think you can save a few bytes: function(s)(s=substr(strsplit(s,' |-')[[1]],1,1))[s%in%LETTERS] – Scarabee Jul 23 '17 at 0:00
• @Scarabee thank you. sorry it took 2 years to update. – Giuseppe Jul 18 '19 at 16:09

# Python 2, 59 56 bytes

-3 bytes thanks to Lynn

lambda s:[b for a,b in zip(' '+s,s)if'@'<b<'['>a in' -']


Try it online!

• I borrowed your trick '@'<b<'[', very nice solution +1 – Mr. Xcoder Jul 21 '17 at 13:36
• Don’t forget about comparison chaining! '@'<b<'['>a in' -' saves 3 bytes. – Lynn Jul 21 '17 at 14:50

# Javascript 21 bytes

Takes a string input and outputs an array of strings containing the acronym characters

x=>x.match(/\b[A-Z]/g)


## Explanation

It's just a global regex match for word-boundary followed by a capital letter.

# Retina, 21 17 bytes

!(?<=^| |-)[A-Z]


Try it online!

### Explanation

Outputs the matches of the regex (?<=^| |-)[A-Z] in the input, one per line (!).

# Dyalog APL, 29 23 bytes

Bonus test case: A Programming Language (APL).

'(?<=^| |-)[A-Z]'⎕S'&'⊢


Returns an array of chars (shows as space seperated on TIO).

Try it online!

### Older post, 29 bytes

{(⎕AV~⎕A)~⍨'(\w)\w+'⎕R'\1'⊢⍵}


Try it online!

How?

'(\w)\w+'⎕R - replace each cluster of alphabetic chars

'\1' - with its first character

~⍨ - remove every char

(⎕AV~⎕A) - that is not an ASCII uppercase

# Python, 53 bytes

import re
lambda s:re.findall("(?<=[ -])[A-Z]"," "+s)


Try it online!

A simple regular expression with a lookahead for space or dash. Rather than matching the start, prepend a space.

• Edited in a TIO link with MrXCoder's test suite. – Stephen Jul 21 '17 at 13:54
• Thanks @StepHen -- you beat me to it and saved me the effort – Chris H Jul 21 '17 at 13:55
• 50 – negative seven Jul 18 '19 at 14:55

# C#, 84 78 bytes

using System.Linq;s=>s.Where((c,i)=>c>64&c<91&(i>0?s[i-1]==32|s[i-1]==45:1>0))


Saved 6 bytes thanks to @jkelm.

Try it online!

Full/Formatted Version:

using System.Collections.Generic;
using System.Linq;

class P
{
static void Main()
{
System.Func<string, IEnumerable<char>> f = s => s.Where((c, i) => c > 64 & c < 91 & (i > 0 ? s[i-1] == 32 | s[i-1] == 45: 1 > 0));

System.Console.WriteLine(string.Concat(f("Self-contained Underwater Breathing Apparatus")));
System.Console.WriteLine(string.Concat(f("a Programming Language")));
System.Console.WriteLine(string.Concat(f("NATO Atlantic TREATY Organization")));
System.Console.WriteLine(string.Concat(f("DEFCON 2")));
System.Console.WriteLine(string.Concat(f("hello, world!")));
System.Console.WriteLine(string.Concat(f("light-Emitting dioDe")));
System.Console.WriteLine(string.Concat(f("What Does the Fox Say?")));
System.Console.WriteLine(string.Concat(f("3D mov-Ies")));
System.Console.WriteLine(string.Concat(f("laugh-Out Lou-D")));
System.Console.WriteLine(string.Concat(f("Best friends FOREVE-r")));
System.Console.WriteLine(string.Concat(f(" ")));
System.Console.WriteLine(string.Concat(f("--  --a -  - --")));
System.Console.WriteLine(string.Concat(f("--  -- -  - -- A")));

}
}

• Why do you have to include using System.Linq in the byte count if using System.Collections.Generic is exempt? Is there some consensus on which using's are countable? – user20151 Jul 21 '17 at 14:04
• @DaveParsons using System.Linq; is needed for the Linq code in my answer. However, IEnumerbale<char> is not part of the answer and that is the part of the code that needs using System.Collections.Generic; to compile. – TheLethalCoder Jul 21 '17 at 14:05
• makes sense; thanks for clarification. – user20151 Jul 21 '17 at 14:08
• You could save a few bytes by checking uppercase using the chars as ints. c>64&c<91 should net you 6 bytes. – jkelm Jul 21 '17 at 14:47
• @jkelm Nice :) I always forget about that trick! – TheLethalCoder Jul 21 '17 at 14:49

# Julia 0.6.0 (57 bytes)

s=split(s,r" |-");for w∈s isupper(w[1])&&print(w[1])end


Explanation: This is my first code-golf. Pretty straight forward. Split the words, print 1rst upper letter of each.

Probably easy to do better using regex but I am new to this

• Welcome to PPCG! I'm out of votes right now, I'll upvote this later. – Stephen Jul 21 '17 at 20:40
• @StepHen I've gotchoo covered. :P – James Jul 21 '17 at 20:42

# 05AB1E, 11 bytes

'-ð‡ð¡ζнAuÃ


Try it online!

# C# (.NET Core), 108 bytes

n=>{var j="";n=' '+n;for(int i=0;++i<n.Length;)if(" -".IndexOf(n[i-1])>=0&n[i]>64&n[i]<91)j+=n[i];return j;}


Try it online!

• Haven't checked but changing the if to a ternary might save you bytes. This starts at index 2 instead of 1, just change int i=1 to int i=0 to fix it. Other than that I don't think there's much more you can do here. – TheLethalCoder Jul 21 '17 at 15:00
• A ternary wouldn't help here, as it would be the same byte count as an if statement. However, you are correct in that I need to change the initial i value – jkelm Jul 21 '17 at 15:11
• I wasn't entirely sure but they usually come out shorter so it is always worth a check. – TheLethalCoder Jul 21 '17 at 15:12

# Jelly,  11  10 bytes

-1 byte thanks to Erik the Outgolfer (Ḳ splits at spaces >_<)

⁾- yḲḢ€fØA


As a full program accepts a string and prints the result.

Try it online! or see a test suite.

### How?

⁾- yḲḢ€fØA - Link: list of characters, x       e.g. "Pro-Am Code-golf Association"
y       - translate x with:
⁾-         -   literal list of characters ['-',' '] "Pro Am Code golf Association"
Ḳ      - split at spaces               ["Pro","Am","Code","golf","Association"]
Ḣ€    - head each (1st character of each)      "PACgA"
ØA - yield uppercase alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
f   - filter keep                            "PACA"
- if running as a full program: implicit print

• Umm, why not use Ḳ instead of ṣ⁶? – Erik the Outgolfer Jul 21 '17 at 14:43
• Heh, because I forgot about it. Thanks! – Jonathan Allan Jul 21 '17 at 14:44

# Perl 5, 25 bytes

24 bytes code + 1 for -n.

Annoying that grep -P support variable length look-behind but Perl doesn't :(.

print/(?:^| |-)([A-Z])/g


Try it online! - includes -l to run all tests at once.

• You can do extremely way much so better: Try it online! ;-) – Dada Jul 27 '17 at 11:44
• @Dada Hah! Of course... I'm out ATM but I'll update when I get back. Thanks! I'm quite disappointed I couldn't get s/// or $_= to negate the print... – Dom Hastings Jul 27 '17 at 11:50 • Yeah, I was looking for a single s/// to solve this but it's not obvious... I'm at work, maybe I'll give it another try later! – Dada Jul 27 '17 at 11:53 # MATL, 19 bytes '- 'X{&Yb'^[A-Z]'XX  Try it online! # Brachylog, 2523 22 bytes ,Ṣ↻s₂ᶠ{h∈" -"&t.∧Ạụ∋}ˢ  Try it online! (-2 bytes thanks to @Fatalize.) ,Ṣ↻ % prepend a space to input s₂ᶠ % get all substrings of length 2 from that, to get prefix-character pairs { }ˢ % get the successful outputs from this predicate: h∈" -" % the prefix is - or space &t.∧ % then the character is the output of this predicate if: Ạụ∋ % the alphabet uppercased contains the character  • You can use Ṣ instead of " " to save two bytes – Fatalize Jul 30 '18 at 6:41 # Japt, 1916 14 bytes -2 bytes thanks to Shaggy f/^| |-)\A/ mÌ  Try it online! • Since you're using v2, I think you can change "(^| |-)%A" to /^| |-)\A/ to save a byte – ETHproductions Jul 21 '17 at 19:51 • mf\A -> mÌ to save 2 bytes. – Shaggy Jan 4 '19 at 15:55 # Swift 5, 110 bytes -5 thanks to Cœur import UIKit func f(s:[String]){for i in zip(s,[" "]+s){if i.0.isUppercase()&&"- ".contains(i.1){print(i.0)}}}  ## Detailed Explanation • import Foundation - Imports the module Foundation that is vital for zip(), the main piece of this code. • func f(s:[String]){...} - Creates a function with a parameter s, that is a list of Strings, representing the characters of the input. • for i in zip(s,[" "]+s){...} - Iterates with i through the zip of the input and the input with a space added in the beginning, which is very helpful for getting the previous character in the String. • if - Checks whether: • i.0==i.0.uppercased() - The current character is uppercase, • &&"- ".contains(i.1) - and If the previous character is a space or a dash. • If the above conditions are met, then: • print(i.0) - The character is printed, because it is part of the acronym. • -5 with import UIKit instead of import Foundation. – Cœur Jul 18 '19 at 13:45 # PowerShell, 43 bytes ''+($args|sls '(?<=^| |-)[A-Z]'-a -ca|% m*)


Try it online!

Unrolled:

''+($args|select-string '(?<=^| |-)[A-Z]' -allmatches -caseSensitive|% matches)  # Python 3, 67 bytes lambda x:[c[0]for c in x.replace("-"," ").split()if c[0].isupper()]  Try it online! # Python 3, 73 70 bytes lambda n:[n[x]for x in range(len(n))if'@'<n[x]<'['and(' '+n)[x]in' -']  Try it online! # Explanation • lambda n: - Creates an anonymous lambda-function with a String parameter n. • n[x] - Gets the character of n at index x. • for x in range(len(n)) - Iterates from 0 to the length of n, naming the variable x. • if - Checks: • '@'<n[x]<'[' - If the character is uppercase, • and(' '+n)[x]in' -' - And if it is preceded by a space or a dash in the String formed by a space and n. • Is it bad that I read that as i supper, and I have no idea why? – TheLethalCoder Jul 21 '17 at 13:22 • @TheLethalCoder It's .isupper(), I have no idea what you read :p – Mr. Xcoder Jul 21 '17 at 13:23 # JavaScript (SpiderMonkey), 62 bytes n=s=>(""+s.match(/([ -]|^)[A-Z]/g)).replace(/[ \-,]|null/g,"")  Try it online! # QuadS, 17 bytes (?<=^| |-)[A-Z] &  Try it online! # Pyth, 15 16 bytes @rG1<R1:w"[ -]"3  Test suite # Pyth, 12 bytes @rG1hMcXz\-d  Test suite here. # Bash (grep), 29 28 bytes grep -oP'(?<=^| |-)[A-Z]' a  A port of my python answer but because pgrep supports variable length lookbehinds it's noticeably shorter (even accounting for the overhead of python). Stick the test cases in a file called a, output is 1 character per line. -1 Thanks to Neil • ^| |- might be a shorter test? – Neil Jul 21 '17 at 15:43 • @Neil that works here, thanks. Missed it because it doesn't work in Python – Chris H Jul 21 '17 at 15:58 # RProgN 2, 18 bytes - rû#ùr.'[a-z]'-  ## Explained - rû#ùr.'[a-z]'- - # Push "-" literal, and " " literal. r # replace, Replaces all "-"s with " "s. û # Split, defaultly by spaces. #ù # Push the head function literally. r # Replace each element of the split string by the head function, which gets each first character. . # Concatenate, which collapses the stack back to a string. '[a-z]'- # Push the string "[a-z]" literally, then remove it from the string underneith, giving us our output.  Try it online! # PHP, 62 bytes for(;~$c=$argn[$i++];$p=$c!="-"&$c!=" ")$c<A|$c>Z|$p?:print$c;  Run as pipe with -nR or try it online. other solutions: foreach(preg_split("#[ -]#",$argn)as$s)$s[0]>Z|$s<A?:print$s[0];  # 64 bytes
preg_match_all("#(?<=\s|-)[A-Z]#"," $argn",$m);echo join($m[0]); # 64 bytes preg_match_all("#(?<=\s|-)\p{Lu}#","$argn",$m);echo join($m[0]); # 65 bytes


## C++, 168 bytes

#include<string>
auto a=[](auto&s){auto r=s.substr(0,1);if(r[0]<65||r[0]>90)r="";for(int i=1;i<s.size();++i)if(s[i]>64&&s[i]<91&&(s[i-1]==32||s[i-1]==45))r+=s[i];s=r;};


Output done via the parameter

• Would it be possible to completely remove #include<string> and assume the argument s is a std::string? – Zacharý Oct 5 '17 at 17:01

## Lua, 79 75 bytes

for i=1,#t do for i in(" "..t[i]):gmatch"[%-| ]%u"do print(i:sub(2))end end

Try it!

I stuck a print() before the final end in the try it version because otherwise it's a mess. This program perfectly adheres to the requirements of I/O and matching, but without that extra new line it's pretty hard to read.

Input is given in the form of a table of number:string , number incrementing by 1 each time and starting at 1.

Explanation:

It for loops through a gmatch of each input string. The gmatch search is as follows:

[%-| ] - Group, search for a - or a space

%u - Search for an uppercase character

Then for each match, it prints it out minus the preceding dash or space

Edit: Golfed 4 bytes by removing the declaration of 'a' and adding the space to the input inside the for loop in, as well as changing the sub input to just 2 rather than 2,2 (which produce equivalent results)

# Pyth, 12 bytes

Created one year after the initial answer.

rI#1hMcXQ\-d


Try it online!

### Pyth, 21 bytes

:+dQ"(?<=[ -])[A-Z]"1

• -|  is one byte less than [ -]` – ATaco Jul 23 '17 at 23:45