# Check if a string is entirely made of the same substring

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. This is Code Golf, so shortest answer in bytes for each language wins.

• 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. Apr 24 '19 at 15:14
• Apr 24 '19 at 15:36

# T-SQL, 47 bytes

Using @Xnor's method:

DECLARE @ varchar(max)='ababab'

PRINT sign(charindex(@,left(@+@,len(@)*2-1),2))


Keeping old answer as it contains some nice golfing(67 bytes):

DECLARE @y varchar(max)='abababa'

,@ INT=0WHILE
replace(@y,left(@y,@),'')>''SET
@+=1PRINT @/len(@y)^1


Explanation: This script is repeatingly trying to replace the input '@y' with the first '@' characters of the input '@y' with nothing, while increasing '@'.

if you replace 'ab' in 'ababab' with nothing you have an empty string

Eventually the result will be empty. If this happens when the loop variable is equal to the length of the varchar, the criteria is false/0 because '@'=len(@y) (there was no repeating varchar).

iif(@=len(@y),0,1)


can be golfed into this

@/len(@y)^1


because the length of '@y' can not be 0 and '@' will never exceed the length @y.

Try it online

# 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


# 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. # 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. # 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. # Perl 6, 14 bytes {?/^(.+)$0+$/}  Try it online! # 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  # 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! # 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!

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