# 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. – Erik the Outgolfer Apr 24 at 15:14
• – Erik the Outgolfer Apr 24 at 15:36

# Brachylog, 4 3 bytes

ġ=Ṁ

Try it online!

## Explanation

ġ=Ṁ    Implicit input, say "abcabc"
ġ      Split into chunks of equal lengths (except maybe the last one): ["abc","abc"]
=     Apply the constraint that all of the chunks are equal,
Ṁ    and that there are multiple of them.

The program prints true. if the constraints can be satisfied, and false. if not.

• I was just struggling through trying to get something like ~j↙ or =Ṁc working before I noticed you posted this an hour ago – Unrelated String Apr 24 at 21:27
• Oh, yeah, this could be one byte shorter: ġ=Ṁ – Unrelated String Apr 24 at 21:36
• ( is a variable constrained to be a list of two or more elements) – Unrelated String Apr 24 at 21:39
• @UnrelatedString Great, thanks! I didn't think to check the variables wiki page. – Zgarb Apr 25 at 9:12
• A lot of great answers, and the LUA answer has a special place in my heart. Arnauld's answer is particularly sweet since the original question that I based this on (not the dupe) is actually tagged Javascript. Mainly selecting this one just because it does appear to be the overall shortest for all languages and, as this is my first question, I get a badge. – ouflak May 1 at 6:40

# JavaScript (ES6), 22 bytes

Returns a Boolean value.

s=>/^(.*)\1+$/.test(s) Try it online! # Without a regular expression, 33 29 bytes Returns either null (falsy) or an object (truthy). s=>(s+s).slice(1,-1).match(s) Try it online! NB: Technically, $$\s\$$ is converted to a regular expression for match(), so the above title is a lie. # grep, 19 grep -qxE '(.+)\1+' ### Test while read; do <<<"$REPLY" grep -qxE '(.+)\1+' && t="true" || t="false"
echo "$REPLY:$t"
done < infile

Output:

aa: true
aaa: true
abcabcabc: true
aba: false
ababa: false
weqweqweqweqweqw: false

# Japt, 6 bytes

²é ¤øU

Saved one byte thanks to @Shaggy

Try it online!

Implicit input, stored in variable 'U'
²       U+U, "abcabc" -> "abcabcabcabc"
é      Rotate 1 char to the right "abcabcabcabc" -> "cabcabcabcab"
¤    Remove first two chars, "cabcabcabcab" -> "bcabcabcab"
øU  Check if U is in the above
• Nice one :) You can replace the p<space> with ² to save a byte. – Shaggy Apr 24 at 16:25

# Java, 25 24 bytes

-1 byte thanks to Olivier Grégoire!

s->s.matches("(.+)\\1+")

Try it online!

It's just 1 byte longer than the python answer aaaaa I'm tied now :)

• You can remove the final $as the matches method is an exact match, not a substring match by default. – Olivier Grégoire Apr 24 at 23:18 • I forgot matches adds its own$ to the regex. Thanks! – Benjamin Urquhart Apr 24 at 23:34

# Excel, 26 bytes

=FIND(A1,A1&A1,2)<=LEN(A1)

Inputs from A1, outputs to whatever cell you put this formula.

• You could save 4 bytes if you defined a single-letter range name (e.g. A) and set that as your input. – i_saw_drones Apr 24 at 18:54
• @i_saw_drones - I think that is disallowed by standard I/O rules: here's a link to the meta answer that would apply to that method; it's currently at -36 votes. – Sophia Lechner Apr 24 at 20:17
• Apologies I hadn't seen that post, although thinking about it, isn't A1 also a "variable" since it contains the input value? :) – i_saw_drones Apr 24 at 23:05
• I would feel that way if I were doing anything special with the fact that it's A1 specifically, like if I relied somehow on its ROW(_) being 1. As is, though, it's just the most natural way of providing an Excel function with an arbitrary input. – Sophia Lechner Apr 25 at 17:03

# R, 28 bytes

grepl("(.+)\\1+$",scan(,'')) Try it online! Simple Regex version. R is (sometimes) very similar to Python, so this is similar to TFeld's Python 2 regex answer, albeit shorter! ### Question (if anyone knows the answer) I am still confused why this works, as the substring can be any length and will always work, and still works when I add a letter to the front of a valid string, like "cABABABABAB". If I personally read the regex, I see (.+), which captures any group of any length. And then \\1+$ which repeats the captured group any number of times until the end.

So why doesn't it capture just "AB" and find that it is repeated until the end of the string, especially since there is no restriction specified as to where the substring can start?

• Interesting, this seems to be a bug in R's regex engine. Adding the option perl=TRUE makes it match cABABAB, as you'd expect. Running grep -E '(.*)\1+$' in bash also matches cABABAB, even though grep -E uses ERE, the same regex flavor R is supposed to support. – Grimmy Apr 25 at 15:43 • My guess is that this is an incorrectly applied optimization. Changing .+ at the start of a pattern to ^.+ is an important optimization, but if the .+ is inside capturing parens it stops being valid. – Grimmy Apr 25 at 15:50 # Retina 0.8.2, 9 bytes ^(.+)\1+$

Try it online! Link includes test cases.

# Jelly,  5  4 bytes

I see now that the optimal way is to follow xnor's method!

Ḋ;Ṗw

A monadic Link that accepts a list of characters and outputs an integer - the shortest possible length of a repeating slice or zero if none exists. Note that zero is falsey while non-zero numbers are truthy in Jelly.

Try it online!

### How?

Ḋ;Ṗw - Link: list of characters, S   e.g. "abcabcabc"   or "abababa"
Ḋ    - dequeue S                           "bcabcabc"       "bababa"
Ṗ  - pop from S                         "abcabcab"       "ababab"
;   - concatenate                "bcabcabcabcabcab"       "bababaababab"

# Perl 5-p, 14 bytes

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

Try it online!

# Python 2, 24 bytes

lambda s:s in(s*2)[1:-1]

Try it online!

Shamelessly stolen from xnor's answer to the original question.

More intuitive version:

# Python 2, 5955 53 bytes

lambda s:s in[len(s)/i*s[:i]for i in range(1,len(s))]

Try it online!

Boring regex version:

Try it online!

Defines $:: [Char] -> Bool. Checks if the given string is a prefix of the repetition of any sub-string taken from the end. # C++ (gcc), 36 bytes #define f(x)(x+x).find(x,1)<x.size() Try it online! Another port of xnor's solution. Uses a macro to expand the argument into the expression. The argument is assumed to be of type std::string. # QlikView Variable, 27 bytes This should be defined as a variable, which then allows you to pass parameters, e.g.$1 as your input value.

It returns 0 or -1 (equivalent to QlikView's TRUE() function).

Try it online!

# Icon, 46 bytes

procedure f(s);return find(s,(s||s)[2:-1]);end

Try it online!

Another port of xnor's solution.

# K (oK), 29 bytes

{0<+/(1=#?:)'(0N,'1_!#x)#\:x}

Try it online!

# Red, 72 bytes

func[s][repeat i length? s[parse s[copy t i skip some t end(return 1)]]]

Try it online!

Returns 1 for True

# 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