Check if a string is entirely made of the same substring

24

5

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.

ouflak

Posted 2019-04-24T14:55:05.123

Reputation: 925

4

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 – 2019-04-24T15:14:44.727

Let us continue this discussion in chat.

– Erik the Outgolfer – 2019-04-24T15:36:30.393

Answers

12

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.

Zgarb

Posted 2019-04-24T14:55:05.123

Reputation: 39 083

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 – 2019-04-24T21:27:35.873

4

Oh, yeah, this could be one byte shorter: ġ=Ṁ

– Unrelated String – 2019-04-24T21:36:39.470

( is a variable constrained to be a list of two or more elements) – Unrelated String – 2019-04-24T21:39:09.653

(better TIO link now that I've realized why writeln is broken [I forgot to handle default subscript when I updated it for compatibility with declarative write])

– Unrelated String – 2019-04-24T21:46:36.983

I guess I'll just edit? – Unrelated String – 2019-04-25T00:16:26.800

If I messed anything up feel free to roll it back – Unrelated String – 2019-04-25T00:23:13.397

1@UnrelatedString Great, thanks! I didn't think to check the variables wiki page. – Zgarb – 2019-04-25T09:12:49.890

was added pretty recently, so if you hadn't checked it in the past week or two (or been in the chat room, where it was announced) you'd have no idea it's there. It's certainly not the most intuitive place to look unless you're already in the habit of using Ċ wherever you'd think to use l₂. – Unrelated String – 2019-04-25T09:18:43.890

1A 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 – 2019-05-01T06:40:38.177

19

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.

Arnauld

Posted 2019-04-24T14:55:05.123

Reputation: 111 334

9

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

Thor

Posted 2019-04-24T14:55:05.123

Reputation: 2 526

9

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

Embodiment of Ignorance

Posted 2019-04-24T14:55:05.123

Reputation: 7 014

Nice one :) You can replace the p<space> with ² to save a byte. – Shaggy – 2019-04-24T16:25:34.723

9

Java, 25 24 bytes

-1 byte thanks to Olivier Grégoire!
Boring regex answer

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

Try it online!

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

Benjamin Urquhart

Posted 2019-04-24T14:55:05.123

Reputation: 1 262

3You can remove the final $ as the matches method is an exact match, not a substring match by default. – Olivier Grégoire – 2019-04-24T23:18:56.803

I forgot matches adds its own $ to the regex. Thanks! – Benjamin Urquhart – 2019-04-24T23:34:18.410

7

Excel, 26 bytes

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

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

Sophia Lechner

Posted 2019-04-24T14:55:05.123

Reputation: 1 200

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 – 2019-04-24T18:54:44.040

@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 – 2019-04-24T20:17:34.293

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 – 2019-04-24T23:05:55.960

1I 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 – 2019-04-25T17:03:40.133

7

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?

Sumner18

Posted 2019-04-24T14:55:05.123

Reputation: 1 334

1Interesting, 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 – 2019-04-25T15:43:29.830

2My 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 – 2019-04-25T15:50:29.997

6

Retina 0.8.2, 9 bytes

^(.+)\1+$

Try it online! Link includes test cases.

Neil

Posted 2019-04-24T14:55:05.123

Reputation: 95 035

6

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"
   w - first index of sublist     3  ^---here!             0  (not found)

Jonathan Allan

Posted 2019-04-24T14:55:05.123

Reputation: 67 804

4

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, 59 55 53 bytes

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

Try it online!


Boring regex version:

Python 2, 44 bytes

lambda s:re.match(r'(.+)\1+$',s)>0
import re

Try it online!

TFeld

Posted 2019-04-24T14:55:05.123

Reputation: 19 246

4

Perl 5 -p, 14 bytes

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

Try it online!

Xcali

Posted 2019-04-24T14:55:05.123

Reputation: 7 671

4

Pyke, 4 bytes

+tO{

Try it here!

+    -    input+input
 t   -   ^[1:]
  O  -  ^[:-1]
   { - input in ^

Blue

Posted 2019-04-24T14:55:05.123

Reputation: 26 661

4

Wolfram Language (Mathematica), 24 23 bytes

StringMatchQ[x__..~~x_]

Try it online!

StringMatchQ[           (*a function that checks if its input (string) matches:*)
             x__..      (*a sequence of one or more characters, repeated one or more times*)
                  ~~x_] (*and one more time*)

attinat

Posted 2019-04-24T14:55:05.123

Reputation: 3 495

3

J, 26 25 15 14 bytes

Using xnor method

+./@E.}:@}.@,~

Try it online!

original (two different approaches)

J, 25 bytes

1<1#.(#%#\)=<\+/@E.&:>"{]

Try it online!

J, 26 bytes

1<1#.-@#\([:(-:##{.)<\)"{]

Try it online!

Jonah

Posted 2019-04-24T14:55:05.123

Reputation: 8 729

3

PowerShell, 23 24 bytes

+1 byte to fully match rules

"$args"-match"^(.+)\1+$"

Try it online!

Pretty boring. Based on the other Regex answers. Luckily PowerShell doesn't use \ as an escape character!

Gabriel Mills

Posted 2019-04-24T14:55:05.123

Reputation: 778

it returns true for aabcabc – mazzy – 2019-04-25T03:41:13.367

1@mazzy just fixed! – Gabriel Mills – 2019-04-25T11:38:00.200

3

05AB1E, 5 bytes

xnor's method from the previous question appears to be optimal in 05AB1E as well.

«¦¨så

Try it online! or as a Test Suite

Explanation

«       # append input to input
 ¦¨     # remove the first and last character of the resulting string
   så   # check if the input is in this string

Emigna

Posted 2019-04-24T14:55:05.123

Reputation: 50 798

1Of course.. I was about to make a 05AB1E answer when I saw none were there. Colleague asked me some questions and talked about his vacation. I look back at the screen: one new answer. Tada, beat again XD – Kevin Cruijssen – 2019-04-25T06:55:11.650

@KevinCruijssen: That's typical. Has happened to me a bunch of times as well ;) – Emigna – 2019-04-25T06:56:54.950

3

C# (Visual C# Interactive Compiler), 70 bytes

xnor's shameless adaptation (46 bytes)

s=>(s+s).Substring(1,s.Length*2-2).Contains(s)

My non Regex Solution:

s=>s.Select((x,y)=>y).Count(z=>s.Replace(s.Substring(0,z+1),"")=="")>1

Explanation:

Replace every possible substring that starts at index 0 with an empty string. If the result is an empty string, the string is entirely made of that substring. Since this includes evaluating the entire string with itself, the amount of expected results must be greater than 1.

Example: abcabc

Possible substrings starting at index 0:

'a', 'ab', 'abc', 'abca', 'abcab', 'abcabc'

If we replace them with empty strings

Substring          Result

'a'         =>     'bcbc'
'ab'        =>     'cc'
'abc'       =>     ''
'abca'      =>     'bc'
'abcab'     =>     'c'
'abcabc'    =>     ''

Since there is a substring other than 'abcabc' that returns an empty string, the string is entirely made of another substring ('abc')

Try it online!

Innat3

Posted 2019-04-24T14:55:05.123

Reputation: 791

3

Python 3, 62 60 56 54 bytes

-4 bytes thanx to ArBo

lambda s:s in(len(s)//l*s[:l]for l in range(1,len(s)))
  1. Iterate over all possible prefixes in the string.
  2. Try to build the string out of the prefix.
  3. Return whether this succeeds with any prefix at all.

Try it online!

movatica

Posted 2019-04-24T14:55:05.123

Reputation: 635

1

Nice answer! The f= can be dropped; anonymous functions are generally allowed. Also, by switching to Python 2 and checking membership of a list instead of the any construct, you can get to 55 bytes

– ArBo – 2019-04-26T08:09:50.097

1Nice catch with the list membership, thanx! I won't switch to Python 2, as this is like switching the language, which is obviously not the point here ;)

Also, is there a convenient way to test an anonymous function in TIO, keeping the byte-count? – movatica – 2019-04-26T14:13:01.223

1@movatica In the header, put f = \ (\ is the line continuation character in python) – Artemis still doesn't trust SE – 2019-04-26T15:33:36.473

Annoyingly, \ is also an escape character. Here, without code formatting, is what you should put in the header: f = \ – Artemis still doesn't trust SE – 2019-04-26T15:35:19.610

2

Japt, 10 bytes

Returns a positive number if truthy and 0 if falsey. If you want a bool output just add flag

å+ k@rXÃÊÉ

å+ k@rXÃÊÉ      Full program. Implicit input U.
                    e.g: U = "abcabcabc"
å+              Take all prefixes 
                         U = ["a","ab","abc","abca","abcab","abcabc","abcabca","abcabcab","abcabcabc"]
   k@           Filter U by:
     rXÃ        Values that return false (empty string)
                when replacing each prefix in U
                e.g: ["bcbcbc","ccc","","bcabc","cabc","abc","bc","c",""]
                                take ↑                             and ↑
                     U = ["abc","abcabcabc"]
         ÊÉ     Get U length and subtract 1. Then return the result

Try it online!

Luis felipe De jesus Munoz

Posted 2019-04-24T14:55:05.123

Reputation: 9 639

2

Husk, 6 bytes

Ṡ€ȯhtD

Try it online!

I feel like this is one byte more than optimal, but I couldn't find an arrangement that made the explicit composition ȯ unnecessary.

Explanation

Ṡ€      Find the argument in the result of applying the following function to the argument
  ȯhtD  Duplicate the argument, then remove the first and last elements.

Sophia Lechner

Posted 2019-04-24T14:55:05.123

Reputation: 1 200

2€htD¹ avoids the ȯ. – Zgarb – 2019-04-24T19:30:11.063

That's fantastic! I had thought about λ€htD¹ but I didn't realize that lambdas would be added implicitly – Sophia Lechner – 2019-04-24T20:10:44.867

2

Mathematica 11.x, 74 bytes

{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&

where, throughout, # represents the input string, and

StringCases[#,<pattern>]

finds substrings of the input string matching the pattern

StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="") 

This pattern requires matches, x, must start at the start of the string and must satisfy the condition that (1) the match is not the whole input string and (2) if we replace occurrences of the match in the input string with the empty string we obtain the empty string. Finally, comparing the list of matches to the empty list,

{}!=

is True if the list of matches is nonempty and False if the list of matches is empty.

Test cases:

{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["aa"]
(*  True  *)
{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["aaa"]
(*  True  *)
{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["abcabc"]
(*  True  *)

and

{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["aba"]
(*  False  *)
{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["ababa"]
(*  False  *)
{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["weqweqweqweqweqw"]
(*  False  *)

Eric Towers

Posted 2019-04-24T14:55:05.123

Reputation: 706

2

Python 3, 84 bytes

import textwrap
lambda s:any(len(set(textwrap.wrap(s,l)))<2 for l in range(1,len(s)))

Uses textwrap.wrap (thanks to this answer) to split the string into pieces of length n to test each possible length of repeating substring. The split pieces are then compared to each other by adding them to a set. If all of the pieces are equal, and the set is of length 1, then the string must be a repeating string. I used <2 instead of ==1 because it saves a byte, and the length of the input string was guaranteed to be greater than zero.

If there is no n for which repeating substrings of length n make up the entire string, then return false for the whole function.

Delya Erricson

Posted 2019-04-24T14:55:05.123

Reputation: 81

2

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.

jxh

Posted 2019-04-24T14:55:05.123

Reputation: 331

2

Clean, 73 bytes

Doesn't use regex.

import StdEnv,Data.List
$s=or[isPrefixOf s(cycle t)\\t<-tl(tails s)|t>[]]

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.

Οurous

Posted 2019-04-24T14:55:05.123

Reputation: 7 916

2

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)

iBug

Posted 2019-04-24T14:55:05.123

Reputation: 2 477

1

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

t-clausen.dk

Posted 2019-04-24T14:55:05.123

Reputation: 2 874

1

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).

=substringcount($1&$1,$1)>2

i_saw_drones

Posted 2019-04-24T14:55:05.123

Reputation: 413

1

Swift, 196 bytes

func r(s:String)->Bool{guard let k=s.dropFirst().firstIndex(where:{$0==s.first}) else{return false};let v=s[...k].dropLast();var w=v;while s.hasPrefix(w) && s.count>=(w+v).count{w+=v};return s==w}

Try it online!

onnoweb

Posted 2019-04-24T14:55:05.123

Reputation: 211

I don't use Swift, but I'm sure that extra whitespace can be removed – Benjamin Urquhart – 2019-04-24T19:56:53.553

193 bytes using @benjamin's suggestion. – Artemis still doesn't trust SE – 2019-04-26T15:39:40.630

@ArtemisFowl or even 123 bytes

– Roman Podymov – 2019-04-26T16:59:39.843

1

Icon, 46 bytes

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

Try it online!

Another port of xnor's solution.

Galen Ivanov

Posted 2019-04-24T14:55:05.123

Reputation: 13 815

1

K (oK), 29 bytes

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

Try it online!

Galen Ivanov

Posted 2019-04-24T14:55:05.123

Reputation: 13 815

1

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

Galen Ivanov

Posted 2019-04-24T14:55:05.123

Reputation: 13 815

1

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

Thor

Posted 2019-04-24T14:55:05.123

Reputation: 2 526

1

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.

Tau

Posted 2019-04-24T14:55:05.123

Reputation: 1 935

1

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.

jxh

Posted 2019-04-24T14:55:05.123

Reputation: 331

1

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.

GammaFunction

Posted 2019-04-24T14:55:05.123

Reputation: 2 838

1

Perl 6, 14 bytes

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

Try it online!

Phil H

Posted 2019-04-24T14:55:05.123

Reputation: 1 376

1

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!

Roman Podymov

Posted 2019-04-24T14:55:05.123

Reputation: 151

1

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

snail_

Posted 2019-04-24T14:55:05.123

Reputation: 1 982

1

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!

user0721090601

Posted 2019-04-24T14:55:05.123

Reputation: 928

0

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!

ouflak

Posted 2019-04-24T14:55:05.123

Reputation: 925