15
\$\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\$
    – Adám
    Jan 21 at 15:39
  • 1
    \$\begingroup\$ The challenge was editted to specify the length of the input, such that edgecases are omitted. \$\endgroup\$
    – Sunny Lu
    Jan 21 at 16:12
  • 1
    \$\begingroup\$ A test case with multiple solutions might be nice. SNYYNYY. \$\endgroup\$
    – Wheat Wizard
    Jan 21 at 19:23
  • \$\begingroup\$ Related, almost duplicate. \$\endgroup\$
    – Fmbalbuena
    Jan 21 at 19:34
  • \$\begingroup\$ @Adám Nonsense! \$\endgroup\$
    – Neil
    Jan 21 at 19:49

19 Answers 19

9
\$\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\$
    – pxeger
    Jan 24 at 18:46
  • \$\begingroup\$ @pxeger I've added a non-regex version. But there may be a shorter way. \$\endgroup\$
    – Arnauld
    Jan 24 at 21:59
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\$
6
\$\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\$
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\$
    – Wheat Wizard
    Jan 22 at 5:03
  • \$\begingroup\$ Also I'm not sure if this is valid since some potential cases like SNYYNYY produce multiple 1s. \$\endgroup\$
    – Wheat Wizard
    Jan 22 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\$
    – Kirill L.
    Jan 22 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
2
\$\begingroup\$

Uiua, 45 bytes

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

Test pad

\$\endgroup\$
6
  • \$\begingroup\$ 25 bytes: this \$\endgroup\$
    – Tbw
    Jan 22 at 7:00
  • \$\begingroup\$ 22 bytes: Pad \$\endgroup\$
    – Tbw
    Jan 22 at 16:36
  • \$\begingroup\$ 21 bytes: Pad \$\endgroup\$
    – Tbw
    Jan 23 at 17:57
  • \$\begingroup\$ Uiua changed, so those first two pads don't work anymore :) \$\endgroup\$
    – Tbw
    Jan 24 at 21:15
  • \$\begingroup\$ They still work, it's just that they won't work later \$\endgroup\$
    – Joao-3
    Jan 25 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
2
\$\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\$ Jan 22 at 23:31
  • 1
    \$\begingroup\$ Ah, of course, thanks. (That's -2 bytes, actually.) \$\endgroup\$
    – DLosc
    Jan 22 at 23:36
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\$

Scala 3, 32 bytes

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

Attempt This Online!

\$\endgroup\$
1
\$\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, 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\$
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\$
    – Sunny Lu
    Jan 23 at 11:25
  • \$\begingroup\$ @Sny Smartie I know, but I don't know them very well! \$\endgroup\$
    – SevC_10
    Jan 23 at 13:40
0
\$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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