24
\$\begingroup\$

This is taken from this question (with permission ofcourse). I'll quote:

Create a function which takes a string, and it should return true or false based on whether the input consists of only a repeated character sequence. The length of given string is always greater than 1 and the character sequence must have at least one repetition.

Some examples:

'aa' //true
'aaa' //true
'abcabcabc' //true
'aba' //false
'ababa' //false
'weqweqweqweqweqw' // false

Specifically, the check for a string strictly composed of repeating substrings (Update) can output any true or false representation, but no error output please. Strictly alphhanumeric strings. Otherwise standard code golf rules. Shortest answer in bytes for each language wins.

\$\endgroup\$
  • 3
    \$\begingroup\$ Hm, I was going to close this challenge as a dupe of that one, but I noticed that the other one scores on character count. So maybe we should close the other one (it also has an accepted answer) as a dupe of this one instead. \$\endgroup\$ – Erik the Outgolfer Apr 24 at 15:14
  • \$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$ – Erik the Outgolfer Apr 24 at 15:36

40 Answers 40

1
\$\begingroup\$

sed, 48

Using the more efficient algorithm described in this answer:

s=abcabc
<<<"$s" sed -nE 's/.*/&\n&&/; /^([^\n]+)\n..*\1.*.$/!q5' \
  && echo true \
  || echo false
\$\endgroup\$
1
\$\begingroup\$

Zsh, 19 bytes

Outputs via error code:

[[ $1$1 = ?*$1*? ]]

Try it online!

However, the challenge did specify "output on stdout":

Zsh, 22 bytes

Outputs an empty string if true, and a non-empty string for false:

<<<${${:-$1$1}/?*$1*?}

If the output must be fixed:

Zsh, 25 bytes

Outputs 0 for true, 1 for false

[[ $1$1 = ?*$1*? ]]
<<<$?

Try it online!


The heart of these solutions is ?*$1*?, which is a glob which matches the string in question surrounded by at least one character on each side: * is a string of any length, and ? is a single character. This is an alternate version of xnor's solution, but using globs to match extra characters rather than removing leading and trailing characters.

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

TI-BASIC, 14 bytes

length(Ans)>inString(Ans+Ans,Ans,2

Input is a string in Ans.
Output is true (1) or false (0) as requested by the challenge.

Examples:

"HELLO
HELLO
prgmCDGF17
               0
"AB
AB
prgmCDGF17
               0
"ABAB
ABAB
prgmCDGF17
               1

Explanation:

length(Ans)>inString(Ans+Ans,Ans,2   ;full program

            inString(                ;get the index of
                             Ans,    ; the input in
                     Ans+Ans,        ; the input concatenated with itself
                                 2   ; starting at the second character
                                     ; (returns index of concatenated piece
                                     ;  if not found elsewhere)
length(Ans)                          ;and then get the length of the input
           >                         ;is the length greater than the index?
                                     ; result is left in "Ans"
                                     ; 1 if true, 0 if false
                                     ;implicit print of "Ans"

Note: TI-BASIC is a tokenized language. Character count does not equal byte count.

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

C (gcc), 37 bytes

#define f(x)strcmp(strstr(1+x x,x),x)

Try it online!

Yet another port of xnor's solution. Using C macros to create the concatenated string, where the macro assumes the argument is a string literal.

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

Perl 6, 14 bytes

{?/^(.+)$0+$/}

Try it online!

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

GNU Bash, 28 bytes

[[ ${1:1}${1::-1} == *$1* ]]

Save the above script into a file, and run bash file.sh "string to test".

Exit code 0 is truthy and non-zero is falsy. (as all Unix shells would interpret)

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

SmileBASIC 3, 72 bytes

Prints 1 for true and 0 for false.

LINPUT L$W=LEN(L$)FOR I=1TO W/2IF LEFT$(L$,I)*(W/I)==L$THEN?1STOP
NEXT?0

Explained

LINPUT L$       'read line of input
W=LEN(L$)       'store length of input
FOR I=1 TO W/2  'loop over all prefixes
 'if this prefix repeated to length of input equals input, print 1 and stop
 IF LEFT$(L$,I)*(W/I)==L$ THEN ?1 STOP
NEXT
?0              'print 0 because check failed
\$\endgroup\$
1
\$\begingroup\$

Perl 6, 14 bytes

*~~/^(.+)$0+$/

Or for the same amount

{m/^(.+)$0+$/}

Much the same as other answers with a simple regex. First one uses Whatever block and a smart matcher to run the regex, and the second does a match on the block input with the implied value. Both return Match objects which are truthy on success, and Nil which is falsey on fairly.

Try it online!

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

Swift 4.2/Xcode 10.2, 123 84 bytes

(1...s.count-1).contains{s==String(repeating:String(s.prefix($0)),count:s.count/$0)}

Try it online!

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

Lua, 50 bytes

Another port of xnor's solution.

s=io.read()t=s..s print(s.find(t.sub(t,2,#t-1),s))

Prints indexes if true, 'nil' otherwise.

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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