17
\$\begingroup\$

Input

A non-empty string or list of capital letters k with length between 3 to 5000.

Output

A value indicating whether k can be expressed as a+b+b, where a and b are non-empty.

Truthy test cases

SSS SNYYY SNYY SNNYY SNYNY 

Falsy test cases

FALSYTESTCASES FALSYFALSYTESTCASES FALSYTESTCASESXFALSYTESTCASES FALSYTESTCASESFALSYTESTCASES SMARTIEATIE 

Neglegible cases:

XX lowercase 123 ABC (repeated 2000 times) 
\$\endgroup\$
13
  • \$\begingroup\$ Welcome to the site! Interesting challenge, but some test cases would be nice. \$\endgroup\$ Commented Jan 21, 2024 at 15:39
  • 1
    \$\begingroup\$ The challenge was editted to specify the length of the input, such that edgecases are omitted. \$\endgroup\$ Commented Jan 21, 2024 at 16:12
  • 1
    \$\begingroup\$ A test case with multiple solutions might be nice. SNYYNYY. \$\endgroup\$ Commented Jan 21, 2024 at 19:23
  • \$\begingroup\$ Related, almost duplicate. \$\endgroup\$ Commented Jan 21, 2024 at 19:34
  • \$\begingroup\$ @Adám Nonsense! \$\endgroup\$ Commented Jan 21, 2024 at 19:49

20 Answers 20

10
\$\begingroup\$

JavaScript (ES6), 21 bytes

Takes a string and returns a Boolean value.

s=>/.(.+)\1$/.test(s) 

Try it online!


JavaScript (ES6), 59 bytes

A non-regex solution.

s=>(g=i=>s[2*i]&&s.slice(-2*i)==(q=s.slice(-i))+q|g(-~i))`` 

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ I'd be interested to see how much longer a non-regex solution is \$\endgroup\$ Commented Jan 24, 2024 at 18:46
  • \$\begingroup\$ @pxeger I've added a non-regex version. But there may be a shorter way. \$\endgroup\$ Commented Jan 24, 2024 at 21:59
7
\$\begingroup\$

Nekomata + -e, 4 bytes

Jtđ= 

Attempt This Online!

Jtđ= J Split the input into a list of parts t Remove the first part đ Check that there are exactly two remaining parts = Check that the two remaining parts are equal 
\$\endgroup\$
6
\$\begingroup\$

Haskell + hgl, 13 bytes

cP$h_*>h_>~ʃ 

Attempt This Online!

Explanation

This uses the parser library.

h_ parses any non-empty string, so we ask if there is a h_ followed by h_ and then we feed the output of the second h_ into ʃ. Since ʃ parses any fixed string given as input, this means it parses whatever h_ gave again.

cP takes the parser we built and turns it into a function which returns true when there is at least one parse which completely consumes the string.

Reflection

This is such a simple challenge it's hard for this to get any better, but I have some thoughts:

  • (>~ʃ) is a pretty common function. It attempts to parse the result of the last parse again. However unless I assigned it a 2 byte name it wouldn't make any savings in this particular case.
  • (h_*>) might also be useful to have a shortcut for.
\$\endgroup\$
5
\$\begingroup\$

Jelly, 7 bytes

ŒHÐƤḊEƇ 

A monadic Link that accepts a list of characters and yields a non-empty list (truthy) if the input can be expressed as a+b+b or an empty list (falsey) otherwise.

Try it online!

How?

ŒHÐƤḊEƇ - Link: list of characters, S ÐƤ - for suffixes of S: ŒH - split into half (if odd length first half is longer) Ḋ - dequeue (we don't want to test for a+a, only a+b+b) Ƈ - keep those for which: E - all equal? 
\$\endgroup\$
4
\$\begingroup\$

Retina, 8 bytes

.(.+)\1$ 

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Curry (PAKCS), 20 19 bytes

f(_:_++b++b)|b>""=1 

Try it online! with truthy, or

Try it online! with falsy test case.

Thanks for a byte saved by Wheat Wizard.

\$\endgroup\$
3
  • \$\begingroup\$ You should be able to do b>"" instead of b/="" to save 1 byte. \$\endgroup\$ Commented Jan 22, 2024 at 5:03
  • \$\begingroup\$ Also I'm not sure if this is valid since some potential cases like SNYYNYY produce multiple 1s. \$\endgroup\$ Commented Jan 22, 2024 at 5:05
  • \$\begingroup\$ Since the difference is really between "Has some value(s)" and "No value", I'd believe this is fair enough for a truthy/falsy classification, regardless of what the values actually are. \$\endgroup\$ Commented Jan 22, 2024 at 20:18
4
\$\begingroup\$

C (gcc), 67 bytes

n;f(char*s){n=strlen(++s);return~-n&&!bcmp(s-~n/2,s+n%2,n/2)|f(s);} 

Try it online!

-1 byte from ceilingcat

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

Brachylog, 7 5 bytes

-2 bytes thanks to Unrelated String

ba₁ḍ= 

Try it online!

Explanation

b Remove the first character from the input a₁ Get a nonempty suffix of the remaining string ḍ Split it into two halves = Assert that both are identical 

The first b is necessary to prevent the prefix from being empty.

\$\endgroup\$
2
  • \$\begingroup\$ -1 by removing a non-empty prefix ahead of time :P \$\endgroup\$ Commented Jan 22, 2024 at 23:31
  • 1
    \$\begingroup\$ Ah, of course, thanks. (That's -2 bytes, actually.) \$\endgroup\$ Commented Jan 22, 2024 at 23:36
3
\$\begingroup\$

Python 3 with regex, 43 42 bytes

import re f=re.compile(r'.+(.+)\1$').match 

Python3 port of the Javascript answer.

Takes a string for input, returns a re.Match object as truthy, None as falsy.

Try it online!

Python 3 recursive, 53 bytes

by Jitse

f=lambda s,i=0:s>''and(s==i*s[:len(s)//2])|f(s[1:],2) 

Try it online!

Python 3 iterative, 65 59 57 bytes

lambda s:any(s.endswith(2*s[i:],1)for i in range(len(s))) 

Takes a string for input, returns True and False accordingly.

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ f=lambda s,i=0:s>''and(s==i*s[:len(s)//2])|f(s[1:],2) \$\endgroup\$ Commented Jun 6, 2024 at 13:12
2
\$\begingroup\$

Uiua, 45 bytes

S←≡(□↙)+1⊃⇡↯⧻. ∊:⊙□♭⊞(□⊐/⊂⇌⊂⊂.).⊐/⊂∵(□S⊐⇌)S⇌. 

Test pad

\$\endgroup\$
6
  • \$\begingroup\$ 25 bytes: this \$\endgroup\$ Commented Jan 22, 2024 at 7:00
  • \$\begingroup\$ 22 bytes: Pad \$\endgroup\$ Commented Jan 22, 2024 at 16:36
  • \$\begingroup\$ 21 bytes: Pad \$\endgroup\$ Commented Jan 23, 2024 at 17:57
  • \$\begingroup\$ Uiua changed, so those first two pads don't work anymore :) \$\endgroup\$ Commented Jan 24, 2024 at 21:15
  • \$\begingroup\$ They still work, it's just that they won't work later \$\endgroup\$ Commented Jan 25, 2024 at 12:30
2
\$\begingroup\$

Charcoal, 16 bytes

⊙ΦEθ…⮌θκι⁼ιײ∕ι² 

Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - for a+b+b, nothing if not. Explanation:

 θ Input string E Map over characters θ Input string ⮌ Reversed … Truncated to length κ Current index Φ Filtered where ι Reversed suffix (is not empty) ⊙ Any reversed suffix satisfies ι Current reversed suffix ∕ ² First half ײ Repeated twice ⁼ Equals ι Current reversed suffix Implicitly print 
\$\endgroup\$
2
\$\begingroup\$

Vyxal 3, 6 bytes

Ḣᶜϩ½≈a 

Try it Online!

Essentially, a case is truthy if some suffix of the input minus the first character (ensuring a is non empty) can be split into two equal halves.

Explained

Ḣᶜϩ½≈a­⁡​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁤‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢⁡‏⁠‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌­ Ḣ # ‎⁡Remove the first character of the string because it could be `a` ᶜϩ # ‎⁢Over all suffixes: ½ # ‎⁣ Split into halves ≈ # ‎⁤ And test whether both halves are the same a # ‎⁢⁡Output whether any are true. 💎 

Created with the help of Luminespire.

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

Perl 5 -p, 15 13 bytes

-2 bytes thanks to @NahuelFouilleul

$_=/.(.+)\1$/ 

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ -2 bytes Try it online! because a non-empty string before is enough \$\endgroup\$ Commented Jan 22, 2024 at 9:59
2
\$\begingroup\$

R, 24 23 bytes

  • -1 byte thanks to pajonk
\(x)grep('.+(.+)\\1',x) 

Attempt This Online! Not a very special solution (regex taken here), but almost surely it's going to be the shortest one in R (well, until pajonk suggested to replace grepl with grep :).

Attempt This Online!

\$\endgroup\$
1
  • \$\begingroup\$ I think that as per default decision-problem rules you may use just grep (with 1 as truthy and integer(0) as falsy). \$\endgroup\$ Commented Jun 3, 2024 at 10:35
1
\$\begingroup\$

BQN (CBQN), 42 bytes

{∨´(≡˝2‿↑⊸⥊)¨2↓»↓𝕩} 

Attempt This Online!

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

05AB1E, 9 bytes

Three different alternatives:

Explanation:

.œ # Get all partitions of the (implicit) input-string 3ù # Only keep the partitions containing three parts ε # Map over each over each remaining partition: ¦ # Remove the first part Ë # Check if the remaining two parts are equal }à # After the map: check if any is truthy # (which is output implicitly as result) 
.s # Get all suffixes of the (implicit) input-string ¨ # Remove the last suffix (the input itself) ε # Map over each suffix: 2ä # Split it into two equal-sized parts (first part is larger for odd lengths) Ë # Check that both parts are equal }à # After the map: check if any is truthy # (which is output implicitly as result) 
¦ # Remove the first character of the (implicit) input-string D # Duplicate it .s # Pop the copy, and push its prefixes 2× # Double each string Å¿ # Check if the input minus first character ends with a string à # Check if any is truthy # (which is output implicitly as result) 
\$\endgroup\$
1
\$\begingroup\$

Zsh, 57 bytes

repeat $#1-2 {1=${1:1};eval '>${1//${1:0:'{2..$#1}'-1}}'} 

Attempt This Online!

Outputs via exit code.

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

Scala 3, 32 bytes

s=>".+(.+)\\1$".r.findFirstIn(s) 

Attempt This Online!

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

APL+WIN, 39 bytes

Prompts for string.

×+/n=+/¨(n↑¨⊂v)=n↑¨(n←⍳⌊.5×⍴v)↓¨⊂v←⌽1↓⎕ 

Try it online! Thanks to Dyalog Classic

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

Python 3.8, 90 bytes

The function takes as input a string s. It returns 0 for True cases, None for False ones.

def f(s): l=len(s) for i in range(1,l): x=(i+l)//2 if s[i:x]==s[x:]:return 0 return 

Try it online!


Explanation

The function takes as input a string s.

The i loop takes substrings of s representing b+b, starting from the second character in order to leave a non-empty substring a.

x represents the middle of the substring.

The two halves of the substring are compared: if they are equal, return 0. If no equal halves are found, return None.

\$\endgroup\$
2
  • \$\begingroup\$ Surely you can use regex... \$\endgroup\$ Commented Jan 23, 2024 at 11:25
  • \$\begingroup\$ @Sny Smartie I know, but I don't know them very well! \$\endgroup\$ Commented Jan 23, 2024 at 13:40

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.