# 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)

• Welcome to the site! Interesting challenge, but some test cases would be nice.
Commented Jan 21 at 15:39
• The challenge was editted to specify the length of the input, such that edgecases are omitted.
– Sny
Commented Jan 21 at 16:12
• A test case with multiple solutions might be nice. SNYYNYY. Commented Jan 21 at 19:23
• Related, almost duplicate. Commented Jan 21 at 19:34
– Neil
Commented Jan 21 at 19:49

# 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! • I'd be interested to see how much longer a non-regex solution is Commented Jan 24 at 18:46 • @pxeger I've added a non-regex version. But there may be a shorter way. Commented Jan 24 at 21:59 # 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  # 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.

# 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?


# Retina, 8 bytes

.(.+)\1$ Try it online! # 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. • You should be able to do b>"" instead of b/="" to save 1 byte. Commented Jan 22 at 5:03 • Also I'm not sure if this is valid since some potential cases like SNYYNYY produce multiple 1s. Commented Jan 22 at 5:05 • 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. Commented Jan 22 at 20:18 # 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 # 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. • -1 by removing a non-empty prefix ahead of time :P Commented Jan 22 at 23:31 • Ah, of course, thanks. (That's -2 bytes, actually.) Commented Jan 22 at 23:36 # 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, 6559 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!

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

# Uiua, 45 bytes

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


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

# Charcoal, 16 bytes

⊙ΦＥθ…⮌θκι⁼ι×²∕ι²


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
Ｅ                 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


# 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.

# Perl 5-p, 15 13 bytes

-2 bytes thanks to @NahuelFouilleul

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


Try it online!

• -2 bytes Try it online! because a non-empty string before is enough Commented Jan 22 at 9:59

# 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!

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

# BQN (CBQN), 42 bytes

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


Attempt This Online!

# 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)


repeat $#1-2 {1=${1:1};eval '>${1//${1:0:'{2..$#1}'-1}}'}  Attempt This Online! Outputs via exit code. # Scala 3, 32 bytes s=>".+(.+)\\1$".r.findFirstIn(s)


Attempt This Online!

# APL+WIN, 39 bytes

Prompts for string.

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


Try it online! Thanks to Dyalog Classic

# 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.

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