Periksa apakah string sepenuhnya terbuat dari substring yang sama

24

Ini diambil dari pertanyaan ini (dengan izin ofcourse). Saya akan mengutip:

Buat fungsi yang mengambil string, dan itu harus mengembalikan benar atau salah berdasarkan apakah input hanya terdiri dari urutan karakter yang diulang. Panjang string yang diberikan selalu lebih besar dari 1 dan urutan karakter harus memiliki setidaknya satu pengulangan.

Beberapa contoh:

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

Secara khusus, pemeriksaan untuk string yang secara ketat terdiri dari substring berulang ( Pembaruan ) dapat menampilkan representasi benar atau salah, tetapi tidak ada output kesalahan. String alfanumerik yang ketat. Kalau tidak, aturan standar kode golf. Ini adalah Golf Code, jadi jawaban terpendek dalam byte untuk setiap bahasa menang.

ouflak
sumber
4
Hm, saya akan menutup tantangan ini sebagai duplikat dari yang satu itu , tetapi saya perhatikan bahwa yang lainnya mendapat skor dari jumlah karakter. Jadi mungkin kita harus menutup yang lain (itu juga memiliki jawaban yang diterima) sebagai gantinya dari yang ini.
Erik the Outgolfer
Mari kita lanjutkan diskusi ini dalam obrolan .
Erik the Outgolfer

Jawaban:

11

Brachylog , 4 3 byte

ġ=Ṁ

Cobalah online!

Penjelasan

ġ=Ṁ    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.

Program mencetak true.jika kendala dapat dipenuhi, dan false.jika tidak.

Zgarb
sumber
Saya baru saja berjuang melalui mencoba untuk mendapatkan sesuatu seperti ~j↙atau =Ṁcbekerja sebelum saya melihat Anda memposting ini satu jam yang lalu
Unrelated String
4
Oh, ya, ini bisa jadi satu byte lebih pendek:ġ=Ṁ
String tidak terkait
( adalah variabel yang dibatasi untuk menjadi daftar dua elemen atau lebih)
String Tidak Terkait
1
@UnrelatedString Hebat, terima kasih! Saya tidak berpikir untuk memeriksa halaman variabel wiki.
Zgarb
1
Banyak jawaban yang bagus, dan jawaban LUA memiliki tempat khusus di hati saya. Jawaban Arnauld sangat manis karena pertanyaan awal yang saya didasarkan pada ini (bukan dupe) sebenarnya ditandai Javascript. Terutama memilih yang ini hanya karena tampaknya menjadi keseluruhan terpendek untuk semua bahasa dan, karena ini adalah pertanyaan pertama saya, saya mendapatkan lencana.
ouflak
19

JavaScript (ES6), 22 byte

Mengembalikan nilai Boolean.

s=>/^(.*)\1+$/.test(s)

Cobalah online!


Tanpa ekspresi reguler,  33  29 byte

Mengembalikan salah null(falsy) atau objek (benar).

s=>(s+s).slice(1,-1).match(s)

Cobalah online!

NB: Secara teknis, s dikonversi menjadi ekspresi reguler untuk pertandingan () , jadi judul di atas adalah bohong.

Arnauld
sumber
9

grep, 19

grep -qxE '(.+)\1+'

Uji

while read; do 
  <<<"$REPLY" grep -qxE '(.+)\1+' && t="true" || t="false"
  echo "$REPLY: $t"
done < infile 

Keluaran:

aa: true
aaa: true
abcabcabc: true
aba: false
ababa: false
weqweqweqweqweqw: false
Thor
sumber
9

Japt , 6 byte

²é ¤øU

Disimpan satu byte berkat @Shaggy

Cobalah 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
Perwujudan Ketidaktahuan
sumber
Bagus sekali :) Anda dapat mengganti p<space>dengan ²untuk menyimpan byte.
Shaggy
9

Java, 25 24 byte

-1 byte terima kasih kepada Olivier Grégoire!
Jawaban regex membosankan

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

Cobalah online!

Ini hanya 1 byte lebih lama dari jawaban python aaaaa saya terikat sekarang :)

Benjamin Urquhart
sumber
3
Anda dapat menghapus final $karena matchesmetode ini adalah pencocokan tepat, bukan pencocokan substring secara default.
Olivier Grégoire
Saya lupa matchesmenambahkan sendiri $ke regex. Terima kasih!
Benjamin Urquhart
7

Excel, 26 byte

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

Input dari A1, output ke sel apa pun yang Anda masukkan rumus ini.

Sophia Lechner
sumber
Anda dapat menyimpan 4 byte jika Anda menetapkan nama rentang huruf tunggal (mis. A) Dan mengaturnya sebagai input Anda.
i_saw_drones
@ i_saw_drones - Saya pikir itu tidak diizinkan oleh aturan I / O standar: inilah tautan ke jawaban meta yang akan berlaku untuk metode itu; saat ini di -36 suara.
Sophia Lechner
Maaf saya belum melihat posting itu, walaupun memikirkannya, bukankah A1juga "variabel" karena mengandung nilai input? :)
i_saw_drones
1
Saya akan merasa seperti itu jika saya melakukan sesuatu yang istimewa dengan fakta bahwa itu adalah A1 khusus, seperti jika saya mengandalkan entah bagaimana ROW (_) menjadi 1. Namun, itu hanya cara paling alami untuk menyediakan fungsi Excel dengan input sewenang-wenang.
Sophia Lechner
7

R , 28 byte

grepl("(.+)\\1+$",scan(,''))

Cobalah online!

Versi Regex sederhana. R (kadang-kadang) sangat mirip dengan Python, jadi ini mirip dengan jawaban regex Python 2 TFeld, meskipun lebih pendek!

Pertanyaan (jika ada yang tahu jawabannya)

Saya masih bingung mengapa ini bekerja, karena substring dapat panjang dan akan selalu bekerja, dan masih berfungsi ketika saya menambahkan surat ke bagian depan string yang valid, seperti "cABABABABAB". Jika saya secara pribadi membaca regex, saya tahu (.+), yang menangkap grup apa pun dengan panjang apa pun. Dan kemudian \\1+$yang mengulangi kelompok yang ditangkap beberapa kali sampai akhir.

Jadi mengapa tidak menangkap hanya "AB" dan menemukan bahwa itu diulangi sampai akhir string, terutama karena tidak ada batasan yang ditentukan di mana substring dapat mulai?

Sumner18
sumber
1
Menarik, ini sepertinya menjadi bug di mesin regex R. Menambahkan opsi perl=TRUEmenjadikannya cocok denganABABAB, seperti yang Anda harapkan. Berlari grep -E '(.*)\1+$'di bash juga cocok denganABABAB, meskipun grep -Emenggunakan ERE, rasa regex R yang sama seharusnya mendukung.
Grimmy
2
Dugaan saya adalah ini adalah optimasi yang salah diterapkan. Mengubah .+pada awal pola ^.+menjadi pengoptimalan penting, tetapi jika bagian .+dalam menangkap parens itu berhenti valid.
Grimmy
6

Jelly ,  5  4 byte

Saya melihat sekarang bahwa cara optimal adalah mengikuti metode xnor !

Ḋ;Ṗw

Tautan monadik yang menerima daftar karakter dan menghasilkan bilangan bulat - panjang sesingkat mungkin dari irisan berulang atau nol jika tidak ada. Perhatikan bahwa nol adalah falsey sedangkan angka bukan nol adalah benar di Jelly.

Cobalah online!

Bagaimana?

Ḋ;Ṗ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
sumber
4

Bahasa Wolfram (Mathematica) , 24 23 byte

StringMatchQ[x__..~~x_]

Cobalah 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
sumber
3

J , 26 25 15 14 byte

Menggunakan metode xnor

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

Cobalah online!

asli (dua pendekatan berbeda)

J , 25 byte

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

Cobalah online!

J , 26 byte

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

Cobalah online!

Jonah
sumber
3

PowerShell, 23 24 byte

+1 byte untuk sepenuhnya cocok dengan aturan

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

Cobalah online!

Membosankan. Berdasarkan jawaban Regex lainnya. Untungnya PowerShell tidak digunakan \sebagai karakter pelarian!

Gabriel Mills
sumber
kembali trueuntukaabcabc
mazzy
1
@ Mazzy baru saja diperbaiki!
Gabriel Mills
3

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

Adaptasi shameless xnor ( 46 byte )

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

Solusi non Regex saya:

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

Penjelasan:

Ganti setiap substring yang mungkin yang dimulai pada indeks 0 dengan string kosong. Jika hasilnya adalah string kosong, string seluruhnya terbuat dari substring itu. Karena ini termasuk mengevaluasi seluruh string dengan sendirinya, jumlah hasil yang diharapkan harus lebih besar dari 1.

Contoh: abcabc

Substring yang mungkin dimulai dari indeks 0:

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

Jika kita menggantinya dengan string kosong

Substring          Result

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

Karena ada substring selain 'abcabc' yang mengembalikan string kosong, string seluruhnya terbuat dari substring lain ('abc')

Cobalah online!

Innat3
sumber
3

Python 3 , 62 60 56 54 byte

-4 bytes thanx ke ArBo

lambda s:s in(len(s)//l*s[:l]for l in range(1,len(s)))
  1. Ulangi semua kemungkinan awalan dalam string.
  2. Cobalah untuk membangun string dari awalan.
  3. Kembalikan apakah ini berhasil dengan awalan sama sekali.

Cobalah online!

movatica
sumber
1
Jawaban bagus! The f=dapat dijatuhkan; fungsi anonim umumnya diperbolehkan. Selain itu, dengan beralih ke Python 2 dan memeriksa keanggotaan daftar alih-alih anykonstruk, Anda bisa mendapatkan 55 byte
ArBo
1
Tangkapan bagus dengan daftar keanggotaan, thanx! Saya tidak akan beralih ke Python 2, karena ini seperti mengganti bahasa, yang jelas bukan intinya di sini;) Juga, apakah ada cara yang nyaman untuk menguji fungsi anonim di TIO, menjaga byte-count?
movatica
1
@movatica Di header, tuliskan `f =` (\ adalah karakter kelanjutan garis dengan python)
Artemis mendukung Monica
Mengganggu, \ juga merupakan karakter pelarian. Di sini, tanpa pemformatan kode, adalah apa yang harus Anda masukkan ke dalam tajuk: f = \
Artemis mendukung Monica
2

Japt , 10 byte

Mengembalikan angka positif jika benar dan 0 jika palsu. Jika Anda ingin hasil bool, tambahkan saja 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

Cobalah online!

Luis felipe De jesus Munoz
sumber
2

Sekam , 6 byte

Ṡ€ȯhtD

Cobalah online!

Saya merasa ini adalah satu byte lebih dari optimal, tetapi saya tidak dapat menemukan pengaturan yang membuat komposisi eksplisit ȯ tidak perlu.

Penjelasan

Ṡ€      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
sumber
2
€htD¹menghindari ȯ.
Zgarb
Itu luar biasa! Saya telah memikirkan λ€htD¹tetapi saya tidak menyadari bahwa lambda akan ditambahkan secara implisit
Sophia Lechner
2

Mathematica 11.x, 74 bytes

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

di mana, sepanjang, #mewakili string input, dan

StringCases[#,<pattern>]

menemukan substring dari string input yang cocok dengan pola

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

Pola ini memerlukan kecocokan,, xharus dimulai pada awal string dan harus memenuhi ketentuan bahwa (1) kecocokan bukan keseluruhan string input dan (2) jika kita mengganti kemunculan kecocokan dalam string input dengan string kosong kami mendapatkan string kosong. Akhirnya, membandingkan daftar kecocokan dengan daftar kosong,

{}!=

aku s True jika daftar kecocokan adalah kosong dan Falsejika daftar kecocokan kosong.

Kasus uji:

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

dan

{}!=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
sumber
2

Python 3, 84 byte

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

Menggunakan textwrap.wrap(terima kasih atas jawaban ini ) untuk membagi string menjadi potongan-potongan panjang nuntuk menguji setiap kemungkinan panjang pengulangan substring. Potongan dibagi kemudian dibandingkan satu sama lain dengan menambahkannya ke set. Jika semua bagiannya sama, dan himpunannya memiliki panjang 1, maka string harus berupa string yang berulang. Saya menggunakan <2alih-alih ==1karena menghemat byte, dan panjang string input dijamin lebih besar dari nol.

Jika tidak ada nyang panjang substring berulang nmembentuk seluruh string, maka kembalikan false untuk seluruh fungsi.

Delya Erricson
sumber
2

05AB1E , 5 byte

Metode xnor dari pertanyaan sebelumnya tampaknya juga optimal di 05AB1E.

«¦¨så

Cobalah online! atau sebagai Test Suite

Penjelasan

«       # append input to input
 ¦¨     # remove the first and last character of the resulting string
   så   # check if the input is in this string
Emigna
sumber
1
Tentu saja .. Saya baru akan membuat jawaban 05AB1E ketika saya melihat tidak ada di sana. Kolega mengajukan beberapa pertanyaan dan berbicara tentang liburannya. Saya melihat kembali ke layar: satu jawaban baru. Tada, kalahkan lagi XD
Kevin Cruijssen
@KevinCruijssen: Itu tipikal. Telah terjadi pada saya beberapa kali juga;)
Emigna
2

Bersih , 73 byte

Tidak menggunakan regex.

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

Cobalah online!

Mendefinisikan $ :: [Char] -> Bool.
Cek apakah string yang diberikan adalah awalan dari pengulangan sub-string yang diambil dari bagian akhir.

Suram
sumber
2

C ++ (gcc) , 36 byte

#define f(x)(x+x).find(x,1)<x.size()

Cobalah online!

Port lain dari solusi xnor. Menggunakan makro untuk memperluas argumen ke ekspresi. Argumen tersebut dianggap bertipe std::string.

jxh
sumber
1

Variabel QlikView, 27 byte

Ini harus didefinisikan sebagai variabel, yang kemudian memungkinkan Anda untuk melewati parameter, misalnya $1sebagai nilai input Anda.

Ia mengembalikan 0atau -1(setara dengan TRUE()fungsi QlikView ).

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

Swift, 196 byte

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}

Cobalah online!

onnoweb
sumber
Saya tidak menggunakan Swift, tapi saya yakin spasi tambahan bisa dihapus
Benjamin Urquhart
193 byte menggunakan saran @ benjamin.
Artemis mendukung Monica
@ArtemisFowl atau bahkan 123 byte
Roman Podymov
1

Ikon , 46 byte

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

Cobalah online!

Port lain dari solusi xnor.

Galen Ivanov
sumber
1

Merah , 72 byte

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

Cobalah online!

Pengembalian 1untukTrue

Galen Ivanov
sumber
1

T-SQL, 47 byte

Menggunakan metode @ Xnor :

DECLARE @ varchar(max)='ababab'

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

Menjaga jawaban lama karena berisi golf yang bagus (67 byte):

DECLARE @y varchar(max)='abababa'

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

Penjelasan: Skrip ini berulang kali mencoba mengganti input '@y' dengan karakter '@' pertama dari input '@y' tanpa apa-apa, sambil meningkatkan '@'.

jika Anda mengganti 'ab' di 'ababab' dengan tidak ada yang Anda miliki string kosong

Akhirnya hasilnya akan kosong. Jika ini terjadi ketika variabel loop sama dengan panjang varchar, kriterianya salah / 0 karena '@' = len (@y) (tidak ada varchar berulang).

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

bisa bermain golf dalam hal ini

@/len(@y)^1

karena panjang '@ y' tidak boleh 0 dan '@' tidak akan pernah melebihi panjang @ y.

Cobalah online

t-clausen.dk
sumber