10
\$\begingroup\$

The Typical Way to Make an Acronym Out of a Phrase Is to Take the First Letter of Each Word: TTWMAOPITFLEW. howeveR, sometimEs, you can make an acronym of random leTters In a seNtence such As like this: RETINA. The only condition is that the letters have to be in the correct order. For instance:

  • LORD can be acronymised from Hello World: heLlO woRlD
  • LEOD cannot be acronymised from Hello World, as no ls are before e

Your task is to take two strings as input as to determine if one can be acronymised into the other.

The first input, the phrase, will only contain letters (A-Z or a-z) and spaces, and the second input, the acronym, will only contain letters (A-Z or a-z). The acronym will always be shorter, or of equal size, to the phrase, and both the acronym and the phrase will be, at minimum, 1 letter long. You may choose which case (upper or lower) you want the inputs to be.

You may choose any two values to represent true and false, as long as those values are consistent.

This is so the shortest code in bytes wins

Examples

HELLO WORLD, LORD -> true
CODE GOLF AND CODING CHALLENGES, DANGLE -> true
SANDBOX FOR PROPOSED CHALLENGES, CODE -> false
HELLO WORLD, LLLD -> true
HELLO WORLD, LLDL -> false
NEW YORK POLICE DEPARTMENT, NOODLE -> false
MASSACHUSETTS INSTITUTE OF TECHNOLOGY, MUTTON -> true
BOB, BOB -> true
PRESIDENT OF THE UNITED STATES, I -> true
\$\endgroup\$
10
  • 5
    \$\begingroup\$ Probably a duplicate of this - someone else can hammer closed if I am correct. \$\endgroup\$ Aug 20, 2019 at 17:46
  • 2
    \$\begingroup\$ Having read through this and the proposed duplicate I am firmly of the opinion answers are transferable in either direction. \$\endgroup\$ Aug 20, 2019 at 18:00
  • 1
    \$\begingroup\$ @JonathanAllan Agreed, some of the answers are even identical. \$\endgroup\$
    – xnor
    Aug 20, 2019 at 18:01
  • 1
    \$\begingroup\$ @AZTECCO with 23 answers here it would probably be better to start a new question instead of fixing this one up. \$\endgroup\$ Aug 20, 2019 at 20:33
  • 3
    \$\begingroup\$ There is no need to downvote this challenge simply for being a duplicate. If the fact that this is a duplicate wasn't caught in the Sandbox, there's nothing I could've done to prevent this being a duplicate. \$\endgroup\$ Aug 21, 2019 at 14:01

23 Answers 23

8
\$\begingroup\$

Brachylog, 1 byte

Try it online!

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Sometimes golfing is simply finding the right language for the job. :) \$\endgroup\$ Aug 20, 2019 at 13:53
5
\$\begingroup\$

Java 8, 46 39 38 35 bytes

a->b->a.matches(b.replace("",".*"))

-7 bytes thanks to @tsh.
-1 byte thanks to @NahuelFouilleul.

Try it online.

Explanation:

a->b->         // Method with two String parameters and boolean return-type
  a.matches(   //  Check if the first input matches the regex:
   b           //   The second input,
    .replace("",".*"))
               //   where every character is surrounded with ".*"

For example:

a="HELLO WORLD"
b="LORD"

Will do the check:

"HELLO WORLD".matches("^.*L.*O.*R.*D.*$")

(The ^...$ will add the String#matches builtin implicitly, since it will always try to match the entire String.)

\$\endgroup\$
6
  • \$\begingroup\$ Will replacing "|" by ".*" work? \$\endgroup\$
    – tsh
    Aug 21, 2019 at 2:24
  • \$\begingroup\$ @tsh I don't think so. "nothing or L or O or R or D or nothing" isn't exactly correct if I do that replacement, whereas the current regex is "any-character(s) L any-character(s) O any-character(s) R any-character(s) D any-character(s)" \$\endgroup\$ Aug 21, 2019 at 6:12
  • 1
    \$\begingroup\$ I meant a->b->a.matches(b.replaceAll("|",".*")) \$\endgroup\$
    – tsh
    Aug 21, 2019 at 6:15
  • \$\begingroup\$ @tsh Oh, yes, that indeed works. That's pretty ingenious, thanks! I was a bit confused when I misinterpret your first comment, since you definitely already knew what I was stating. ;) \$\endgroup\$ Aug 21, 2019 at 6:21
  • 2
    \$\begingroup\$ why not replaceAll("",".*") \$\endgroup\$ Aug 21, 2019 at 11:53
4
\$\begingroup\$

C (gcc), 47 bytes

f(a,b)char*a,*b;{a=!*b||*a&&f(a+1,b+(*a==*b));}

Try it online!

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

05AB1E, 3 bytes

æIå

Try it online!

æ              # power set of the first input
 I             # second input
  å            # does a contain b?
               # implicit output
\$\endgroup\$
3
\$\begingroup\$

Python 2, 48 bytes

lambda s,a:re.search('.*'.join(a),s)>0
import re

Try it online!

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

APL (Dyalog Unicode), 17 bytes

Full program. Prompts for phrase, then acronym.

0∊⊃(⍳⍨↓⊢)/⍞,⊂⌽0,⍞

Try it online!

 prompt for phrase
  "HELLO WORLD"
  "HELLO WORLD"

0, prepend a zero
  [0,'H','E','L','L','O',' ','W','O','R','L','D']
  [0,'H','E','L','L','O',' ','W','O','R','L','D']

 reverse
  ['D','L','R','O','W',' ','O','L','L','E','H',0]
  ['D','L','R','O','W',' ','O','L','L','E','H',0]

 enclose (to treat as a whole)
  [['D','L','R','O','W',' ','O','L','L','E','H',0]]
  [['D','L','R','O','W',' ','O','L','L','E','H',0]]

⍞, prepend the prompted-for acronym:
  ['L','L','L','D',['D','L','R','O','W',' ','O','L','L','E','H',0]]
  ['L','L','D','L',['D','L','R','O','W',' ','O','L','L','E','H',0]]

()/ reduce that list by the following tacit function:

  ⍳⍨ the ɩndex of the first occurrence in the phrase (will return 1 + phrase length if unfound)

  ↓⊢ drop that many characters from the phrase

We then use the shortened phrase to look for the next letter. If at any point a letter is unfound, we'll drop everything, including the final zero. This means that if our acronym is good, we'll still have a zero left.
  [0]
  []

 disclose (because the reduction reduced the number of dimensions from 1 to 0)

0∊ is zero a member thereof?

\$\endgroup\$
2
  • \$\begingroup\$ Looks like APL does not have the "lists must be homogenous in both type and length" constraint that J has. Here the list we're reducing appears to mix characters and a list (the final element). In J you'd need to use boxes for that kind of mixing. \$\endgroup\$
    – Jonah
    Aug 20, 2019 at 15:59
  • 1
    \$\begingroup\$ @Jonah That is correct. We also have 0 and characters in the same vector here. \$\endgroup\$
    – Adám
    Aug 20, 2019 at 16:12
3
\$\begingroup\$

J, 21 bytes

<@[e.]<@#~2#:@i.@^#@]

Try it online!

Note: Some of the longer test cases omitted because they this solution is O(2^n). They would pass with infinite memory.

Explanation: We create all 2 ^ (length of haystack) possible substrings, and check if the needle is an element of that list.

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

Python 3, 89 68 bytes

-21 bytes thanks to AdmBorkBork

def a(b,c):
    for i in b:
        if i==c[:1]:
            c=c[1:]
    return len(c)==0

Takes input as a(string, acronym). Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to CodeGolf.SE! I'm not an expert in Python, but I think you can use tabs instead of spaces to save a bunch of bytes. Try it online! \$\endgroup\$ Aug 20, 2019 at 17:43
  • \$\begingroup\$ AdmBorkBork, I didn't seem to be able to type tabs in the answer box, and I forgot copy and paste. \$\endgroup\$
    – gadzooks02
    Aug 20, 2019 at 17:44
2
\$\begingroup\$

JavaScript, 26 bytes

Port of Kevin's Java solution so please +1 him, too.

Takes the string as a string via parameter s and the acronym as a character array via parameter a. Outputs false for true and true for false.

s=>a=>!s.match(a.join`.*`)

Try it online! (Footer reverses output for easier verification)

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

Gaia, 5 bytes

$z@$Ė

Try it online!

Powerset approach.

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

Japt, 4 bytes

à øV

Try it here

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

Jelly, 4 bytes

eŒP}

Try it online!

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

Zsh, 35 bytes

[[ $1 = *${~${(j:*:)${(s::)2}}}* ]]

Outputs via exit code. Try it online!

[[ $1 = *${~${(j:*:)${(s::)2}}}* ]]
                    ${     2}        # second parameter
                    ${(s::) }        # split into characters
            ${(j:*:)         }       # join with *
         ${~                  }      # enable globbing
        *${~${(j:*:)${(s::)2}}}*     # *A*C*R*O*N*Y*M*
[[ $1 =                           ]] # does it match the first parameter?
\$\endgroup\$
1
\$\begingroup\$

C#, 152 bytes

public class P{public static void Main(string[]a){int q=0;int e=a[1].Length;foreach(char c in a[0])if(q!=e&&c==a[1][q])q++;System.Console.Write(q==e);}}

Try Online

\$\endgroup\$
3
  • \$\begingroup\$ The "Try Online" link 404s for me. Have you tried the fairly conventional website tio.run? I haven't read through your code completely, but you can almost certainly declare q and e together, use var instead of char, use & instead of &&, make the submission a lambda expression ((a,b)=>{...} or even a=>b=>{...}), and use the Visual C# Interactive compiler (that allows you to implicitly use System and some other namespaces, use Print() and multiple similar awesome things). \$\endgroup\$ Aug 20, 2019 at 13:47
  • \$\begingroup\$ Whooops fixed the link. And as to the C# interactive compiler: I simply don't want to use it because I just like my code to be full programs. \$\endgroup\$ Aug 20, 2019 at 14:21
  • \$\begingroup\$ In the upcoming threads I will use tio.run for simplicity sake. \$\endgroup\$ Aug 20, 2019 at 15:28
1
\$\begingroup\$

Python 3, 63 bytes

f=lambda s,t:(t[:1]in{*s}and f(s[s.find(t[0]):],t[1:]))**len(t)

Try it online!

Recursive function. Will check for each letter in the acronym t, whether it is found in the string s. If it is, the function is called recursively with the part of the string after the current test character t[0] as the new input string s.

When the test character is not found, the final evaluation result (which at that point is always 0) is raised to the power of the length of the remaining test string t. Since 0**0 == 1 and 0**x == 0 for any x > 0, the function returns 1 when all test characters have been found in order and 0 otherwise.

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

SNOBOL4 (CSNOBOL4), 88 bytes

	T =INPUT
S	T LEN(1) . X REM . T	:F(M)
	M =M ARB X	:(S)
M	INPUT M	:F(END)
	OUTPUT =1
END

Try it online!

Prints 1 for Acronymizable, and does nothing for not.

	T =INPUT			;* read in the Target
S	T LEN(1) . X REM . T	:F(M)	;* extract the first letter of T
					;* and when T is empty, goto M
	M =M ARB X	:(S)		;* create a PATTERN: M, ARBitrary match, X
					;* then goto S
M	INPUT M	:F(END)			;* if M doesn't match the input, end
	OUTPUT =1			;* else print 1
END
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 50 bytes

h=>n=>[...n].reduce((a,l)=>a+1?h.indexOf(l,a):a,0)

Try it online!

take input as f(haystack)(needle)

h=>n=>                                             // inputs
      [...n]                                       // transform n from string to array of char
            .reduce((a,l)=>                    ,0) // for each letter change the value of a, (a starting at 0)
                           a+1?h.indexOf(l,a):a    // if a === -1 keep it else replace it by the position of the letter l in the haystack h starting from position of previous letter
\$\endgroup\$
1
\$\begingroup\$

Stax, 4 bytes

äΦv>

Run and debug it

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This breaks the rule that the outputs must be consistent \$\endgroup\$ Aug 20, 2019 at 14:21
  • \$\begingroup\$ @cairdcoinheringaahing Updated. Applying !! which will return 1 for true and 0 for false. \$\endgroup\$
    – Oliver
    Aug 20, 2019 at 14:35
1
\$\begingroup\$

Emacs Lisp, 52 bytes

(lambda(a b)(string-match(mapconcat'string b".*")a))
\$\endgroup\$
1
\$\begingroup\$

Pyth, 3 bytes

}Ey

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Somehow Pyth is still managing to beat Jelly, after all these years \$\endgroup\$ Aug 20, 2019 at 15:15
1
\$\begingroup\$

Haskell, 40 bytes

r@(a:c)#(b:d)|a==b=c#d|1>0=r#d
x#y=x==""

Try it online!

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

Python 3, 85 bytes

def f(s,w):
	for c in s:
		if c==w[0]:
			w.pop(0)
			if len(w)==0:return 1
	return 0

Try it online!

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

Retina 0.8.2, 20 19 bytes

+`(.)(.*¶)\1?
$2
¶$

Try it online! Takes the phrase and acronym on separate lines, but the link includes a header that formats the test suite appropriately. Explanation:

+`

Process all of the letters of the phrase.

(.)(.*¶)\1?
$2

For each letter of the phrase delete the next letter of the acronym if it is the same.

¶$

Check that all of the letters of the acronym were deleted.

\$\endgroup\$

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