g | x | w | all
Bytes Lang Time Link
042Python 3 with regex240124T141622Zmovatica
023R240602T184518Zint 21h
032Scala 3240126T125559Z138 Aspe
057Zsh240126T093858Zpxeger
021JavaScript ES6240121T154239ZArnauld
00905AB1E240124T091914ZKevin Cr
067C gcc240122T034656Zl4m2
090Python 3.8240123T102646ZSevC_10
005Brachylog240122T232230ZDLosc
019Curry PAKCS240121T211626ZKirill L
013Perl 5 p240122T070326ZXcali
039APL+WIN240122T144303ZGraham
042BQN CBQN240122T084555ZRazetime
004Nekomata + e240122T014133Zalephalp
006Vyxal 3240122T010221Zlyxal
016Charcoal240121T195419ZNeil
008Retina240121T193309ZFmbalbue
013Haskell + hgl240121T191330ZWheat Wi
045Uiua240121T180339ZJoao-3
007Jelly240121T160324ZJonathan

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!

R, 24 23 bytes

\(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!

Scala 3, 32 bytes

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

Attempt This Online!

Zsh, 57 bytes

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

Attempt This Online!

Outputs via exit code.

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!

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)

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

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.

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.

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.

Perl 5 -p, 15 13 bytes

-2 bytes thanks to @NahuelFouilleul

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

Try it online!

APL+WIN, 39 bytes

Prompts for string.

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

Try it online! Thanks to Dyalog Classic

BQN (CBQN), 42 bytes

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

Attempt This Online!

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

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.

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

Retina, 8 bytes

.(.+)\1$

Try it online!

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:

Uiua, 45 bytes

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

Test pad

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?