String.prototype.isRepeated


41

GÜNCELLEME : isaacg Pyth teslimi kazanan!


Birçoğunuz, şehirde String.prototype.repeatyapabileceğiniz bir yöntemi olan, JavaScript’in daha havalı bir sürümü olduğunu (ES6’yı okuyun) duymuş olmalısınız.

"Hello, World!".repeat(3)

ve Al

"Hello, World!Hello, World!Hello, World!"

çıktı olarak.

İşiniz, bir dizgenin bu tür bir dönüşümün altına girip girmediğini tespit eden , seçtiğiniz bir dilde bir işlev veya program yazmaktır .

yani giriş dizisi ndaha küçük bir dizenin tam tekrarı olarak temsil edilebilir . Çıktı (işlevin return ifadesi ya da STDOUT olarak), dizenin daha küçük bir dizenin tekrarı olarak gösterilememesi durumunda dizge olabiliyorsa ya da sahte ise truthy olmalıdır.

Bazı örnek giriş:

"asdfasdfasdf"  // true
"asdfasdfa"     // false
"ĴĴĴĴĴĴĴĴĴ"     // true
"ĴĴĴ123ĴĴĴ123"  // true
"abcdefgh"      // false

Son girişin yanlış olduğuna dikkat edin, bu nedenle nbüyük1

Tam kuralları

  • Bir dize girmek için herhangi bir dilde bir işlev / program yazın (işlev argümanı / komut satırı args / STDIN ile)
  • Verilen dize daha küçük bir dizenin kesin bir tekrarı ile oluşturulmuşsa, en az iki kez tekrar eden truthy değerini döndürün / yazdırın.
  • Giriş dizesinin maksimum boyutu idealdir
  • Dize olası tüm ASCII karakterlerine sahip olabilir
  • Bu bir , karakterdeki en küçük kod kazanıyor.

Ne "" - boş dize - dönüş? (Boş dizginin sonsuz sayıda kopyasını içerir.)
billpg 17:14

@billpg falsy value
Optimizer

Oy kullanmaya mı başladınız? Yaygın uygulama daha önce yapılan gönderimdir (ilk olarak, bağlama puanına ilk giren kişi). Ancak bunun, herhangi bir yerdeki varsayılan bağlayıcı olarak yazıldığından emin değilim, bu yüzden sonuçta size kalmış.
Martin Ender

Gönderileri arasındaki süre sadece 30 dakikadır. Bunu kazanmaya yetecek kadar düşünmüyorum :). O zaman şimdi değişmeyeceğinden, oylar değişebilir, oy kullandım
Doktor

Bu sorunun adı xnor olarak değiştirilmelidir :) O adam!
Silviu Burcea 19:14

Yanıtlar:


16

Pyth , 9

/:+zz1_1z

Veya

}z:+zz1_1

Her ikisi de @ xnor'ın python yanıtının yakın çevirileridir, ancak STDIN'den girdi almaları ve yazdırmaları dışında. İlk eşdeğerdir:

z = input()
print((z+z)[1:-1].count(z))

False için 0, True için 1.

İkinci satır şuna eşittir:

z = input()
print(z in (z+z)[1:-1])

Yanlış için Yanlış, Doğru için Doğru.

Pyth'in resmi derleyicisinin ikincisiyle ilgili bir hata vardı, bu sadece yeni ekledim, bu yüzden ilk benim resmi sunumum.


Sadece bu hatayı size bildirmenin bir yolunu arıyordum (Boole basılmaz). İlkini düşünmedim ve kullanmak xçok uzun ...
Dennis

Evet, böcek şimdi düzeltildi. Ayrıca, hataları bildirmek istiyorsanız, github sitesinde bir sorun açmak iyi bir yol olabilir, burada: github.com/isaacg1/pyth/issues
isaacg 16:14

Oh, işte orada . GitHub'a nasıl gideceğimi bilmiyorum ve sağdaki gezinti panelini hiç farketmedim ...
Dennis

81

Python (24)

lambda s:s in(s+s)[1:-1]

Dizginin iki kez birleştirilmiş bir alt dize olup olmadığını kontrol eder, önemsiz eşleşmeleri önlemek için ilk ve son karakterleri elimine eder. Eğer öyleyse, kendisinin önemsiz bir döngüsel geçirgenliği ve dolayısıyla tekrarlanan bölümlerin toplamı olmalıdır.


8
Golfscript'e önemsiz bir çeviri 10 karakter verir:..+);(;\?)
Justin

3
Bunun nasıl çalıştığını pek anlamadım. Bunun bir ipte nasıl işleneceğine dair elle açıklanmış bir örnek verebilir misiniz?
Nzall

8
@ NateKerkhofs alır abcabc. s+sdönüşüyor abcabcabcabc. [1:-1]İki ucun eti elde etmek için bcabcabcabcab. ve sonra bunun bir temeli olarak s in ...bulmaya çalışır abcabc. Bu alt dize orijinal yarıdan hiçbirinde bulunamaz, çünkü ikisi de kısaltılmıştır, bu nedenle her iki yarıya da yayılmalıdır. Özellikle, başlangıcından önce, kendi özüne sahip olmalıdır, bu aynı (tekrarlanan) alt dizilerden oluşması gerektiğini gösterir.
Martin Ender

6
İkiye katladıktan sonra doğrayın. abolur ababolur bayanlış döndürür böylece iken, aaolur aaaaolur aadoğrudur döndüren.
histocrat

1
@SargeBorsch Sadece aynı çalışır: qweqweqweiçinde weqweqweqweqweqwolduğunu True.
xnor

30

Regex (ECMAScript lezzet), 11 bayt

Regex için bir iş gibi geliyor!

^([^]+)\1+$

Burada test et.

ECMAScript'i seçtim, çünkü [^]herhangi bir karakterle eşleşen tek lezzet budur (biliyorum) . Diğerlerinde, davranışını değiştirmek için bir bayrağa ihtiyacım var .ya [\s\S]da üç karakterden daha uzun olan kullanımı .

Biz bayrağı sayıyorlar şekline bağlı olarak, bu olabilir elbette bir bayt daha kısa. Örn: desen + bayrakları sayıyorsak (örneğin sınırlayıcıları yok sayarak), PCRE / Perl eşdeğeri

/^(.+)\1+$/s

Sınırlayıcıları yok sayarak 10 bayttır.

Burada test et.

Bu, yalnızca bazı alt dizelerin en az iki tekrarından oluşan dizelerle eşleşir.

İşte tam bir 26 bayt ES6 işlevi, ancak düzenli ifade gönderimlerinin genellikle geçerli olduğunu düşünüyorum:

f=s->/^([^]+)\1+$/.test(s)

^(.+)\1+$9 bayt olan benim için çalışıyor. Senin için çalışmıyor mu?
Doktor

@Optimizer Satır sonları ile bir dize deneyin.
Martin Ender

Denedim asd\nasd\nasd\n. Çalışır
Doktor

@Optimizer refiddle.com/refiddles/5417fb2475622d4df7e70a00 benim için çalışmıyor gibi görünüyor (ve yapmamalı)
Martin Ender

Evet, bu işe yaramıyor. Belki de el ile \ yazdığımda kaçıyor\n
Doktor

12

CJam, 9

q__+)@+#)

Xnor'ın fikrine benzer.

q      " Read input. ";
__+    " Duplicate twice and concatenate them together. ";
)      " Remove the last character of the longer string. ";
@+     " Insert that character at the beginning of the shorter string. ";
#)     " Find the shorter string in the longer string, and increase by one. ";


Final için neden ihtiyaç var )? Bence -1 FALSE ve> = 0 TRUE
Digital Trauma

@DigitalTrauma Ben 0 gibi gve gibi operatörler için CJam ... sahte olduğunu düşünüyorum ?.
jimmy23013

@DigitalTrauma: Sonunda ihtiyaç duyulup duyulmadığı nihai olarak OP'ye bağlıdır, ancak kesin olarak sadece sıfır konuşma CJam'da sahte olarak kabul edilir.
Dennis,

@ user23013 @Dennis Peki ya #işleç operatörü? Şüphesiz bunun sonucu aynı zamanda başarıya karşı başarısızlık perspektifinden "hakikat" mi?
Dijital Travma,

7

APL, 11

2<+/x⍷,⍨x←⍞

Açıklama
dizge girişini ekrana
x←atayarak değişkene x
,⍨bitiştirir , sonuçtaki dizgede kendisi
x⍷aranır x. Bir eşleşmenin başlangıç ​​konumunda 1'lerden ve başka bir yerde 0'lardan oluşan bir dizi döndürür. Toplamı 2'den büyükse
+/dizi
2<kontrolünü toplar (2 önemsiz eşleşme olacağı gibi)


7

CJam, 10 bayt

CJam hatasını yakaladım. İlk cevabım, muhtemelen daha fazla golf olabilir:

q__+(;);\#

FALSE için -1, TRUE için bir sayı> = 0 olarak çıkar.


5
Kulübe hoşgeldin!
Dennis,

5

GolfScript, 10 bayt

..+(;);\?)

Xnor'ın akıllı fikrinin bir başka uygulaması.


Hahaha, Bunu bir dakika önce gönderdim: codegolf.stackexchange.com/questions/37851/… . Cevap olarak yayınlamayı düşündüm, ama önemsiz çevirilerin ilgi çekici olmadığını düşündüm.
Justin,

Bu sefer yeni cevaplar bile kontrol ettim, ancak yeni yorumlar için değil ... Kodunuz yine de eksik ); Eşleşme olmadığında yazdıracaktır -1. Bunu bir cevap olarak gönderecekseniz, memnuniyetle benimkini silerim.
Dennis,

)Cevabınızı yayınlamadan hemen önce ekledim (Yorumu
Justin

1
(CJam olarak) Geliştirilmiş versiyonu: q__+)@+#). GolfScript'te çalışmıyor.
jimmy23013

1
@ user23013: Bir daha olmaz. Sadece bunu gönderecektim! Şu ana kadar orada çok fazla CJammers var ...: P
Dennis

3

Python - 59 57

lambda s:any([s*n==s[:n]*len(s)for n in range(2,len(s))])

3

Saf bash, 30 bayt

@ Xnor'ın akıllı cevabının basit portu :

[[ ${1:1}${1:0: -1} =~ "$1" ]]

Çıkış kodu TRUE için 0 ve FALSE için 1'dir:

$ for s in 'Hello, World!Hello, World!Hello, World!' 'asdfasdfasdf' 'asdfasdfa' 'ĴĴĴĴĴĴĴĴĴ' 'ĴĴĴ123ĴĴĴ123' 'abcdefgh'; do echo "./isrepeated.sh "\"$s\"" returns $(./isrepeated.sh "$s"; echo $?)"; done
./isrepeated.sh "Hello, World!Hello, World!Hello, World!" returns 0
./isrepeated.sh "asdfasdfasdf" returns 0
./isrepeated.sh "asdfasdfa" returns 1
./isrepeated.sh "ĴĴĴĴĴĴĴĴĴ" returns 0
./isrepeated.sh "ĴĴĴ123ĴĴĴ123" returns 0
./isrepeated.sh "abcdefgh" returns 1
$ 

Not =~dahilinde [[ ... ]]olduğu bash regex operatör . Bununla birlikte, "Desenin herhangi bir kısmı, onu bir ip olarak eşlenmeye zorlamak için alıntı yapılabilir" . Bu nedenle ai sık sık bash durumlarında olduğu gibi, doğru alıntı yapmak çok önemlidir.


3

TI-BASIC - 32

Belirlenmiş bir dili deneyebileceğimi düşündüm. Dize Ans ile çalıştırın, yanlış ise 0, yinelenen dizenin uzunluğu true olursa döndürür.

inString(sub(Ans+Ans,1,2length(Ans)-1),sub(Ans,length(Ans),1)+Ans

Tek gömlek nasıl şaşırtıcı.


Ama ... ama ... ben TI-BASIC kullanacaktım: P 1
Timtech

@Timtech Peki, TI-BASIC'de string manipülasyonu deneyenlere dikkat edin: TI-BASIC'de string manipülasyonunu denemeyin. : P Yapması ve iyileştirmesi çok zordu.
Josiah Winslow

İyi bir fikir. Dize manipülasyonu yapılması en zor şeylerden biridir. Ancak, bunun gibi birkaç cevap verdim, bu yüzden şimdi bir rakibiniz olduğunu tahmin ediyorum;)
Timtech

Bırakın gelsin! : P
Josiah Winslow

3

ECMAScript 6 (189)

(function(){var S=String.prototype,r=S.repeat;S.isRepeated=function(){return!1};S.repeat=function(c){var s=new String(r.call(this,c));if(c>1)s.isRepeated=function(){return!0};return s}}());

 

< console.log("abc".isRepeated(),"abc".repeat(10).isRepeated());
> false true

Kesinlikle tek geçerli çözüm bu mu? Örneğin, (string) kelimesi nanamutlaka"na".repeat(2)


"nana"değil, ama soru .repeatkullanılıp kullanılmadığını test etmiyor. Aksine, dizenin tekrarlanan olup olmadığı
Optimizer

Biliyorum, sadece akıllı bir
eşlik

2

ECMAScript 6 (34 36 )

Fakat kullanmadan başka ES6 cevap repeatve kullanma XNOR en trick :

f=i=>(i+i).slice(1,-1).contains(i)

Firefox gibi ES6 özellikli bir tarayıcının konsolunda çalıştırılmalıdır.


2

C 85

l,d;f(s){return l=strlen(s),strstr(d,strcpy(strcpy(d=alloca(l*2+1),s)+l,s)-1)-d-l+1;}

Oldukça uzun olduğu ortaya çıktı ama dış fonksiyonlar hep böyledir. Aklıma geldi, her dize işlevini bir döngü veya özyinelemeli olanla değiştirerek yeniden yazabilirim. Ama benim deneyimlerime göre bu daha uzun sürecek ve açıkçası bunu denemek istemiyorum.

Bazı araştırmalardan sonra yüksek performanslı çözümler gördüm ama xnor'ınki kadar zeki (ve kısa) değil. sadece orjinal olmak için ... aynı fikri c.

açıklama:

int length, 
    duplicate;
int is_repetition(char *input)
{
    // length = "abc" -> 3
    length = strlen(input);
    // alloca because the function name is as long as "malloc" 
    // but you don't have to call free() because it uses the stack
    // to allocate memory
    // duplicate = x x x x x x + x
    duplicate = alloca(length*2 + 1);
    // duplicate = a b c 0 x x + x
    strcpy(duplicate, input);
    // duplicate = a b c a b c + 0
    strcpy(duplicate + length, input);
    if (strstr(duplicate,duplicate + length - 1) != duplicate + length - 1)
        // repetition
        // e.g. abab -> abababab -> aba[babab]
        // -> first occurence of [babab] is not aba[babab]
        // but a[babab]ab -> this is a repetition
        return 1;
    else
        // not repetition
        // e.g. abc -> abcabc -> ab[cabc]
        // -> first occurence of [cabc] is ab[cabc]
        // it matches the last "cabc"
        return 0;
}

1

ECMAScript 6 (59 62 67 73 )

Kazanan değil, aslında repeatişlevi kullanan bu soru için ES6'da en az bir cevap olması gerektiği gibi görünüyor :

f=i=>[...i].some((_,j)=>i.slice(0,j).repeat(i.length/j)==i)

Firefox gibi ES6 özellikli bir tarayıcının konsolunda çalıştırılmalıdır.

Çok fazla gereksiz yineleme yapıyor, ancak neden bundan kaçınmak için daha uzun sürüyor ki?

  • Düzenleme # 1: Bir fonksiyona dönüştürerek birkaç bayt kaydedildi. Doktoru için teşekkürler!
  • Düzenleme # 2: Yayılma operatörü numarasının daha fazla byte kaydetmesi için hsl'ye teşekkürler!
  • Düzenleme # 3: Rob W.'ye 3 bayt için teşekkürler!

Orada daha fazla bayt tasarrufu için bir işleve dönüştürebilirsiniz
Doktor

@Optimizer Doğru, sanırım "stdin" olması gerekmiyor.
İsminize

Bunu test etmedim ama kullanmak mümkün olmalıdır yayılma operatörü için [...i]yerinei.split('')
NinjaBearMonkey

1
@hsl Çılgın, işe yarıyor. Spread operatörünün böyle çalıştığını bilmiyordum. Başlangıçta dizi ile bir dizi oluşturmak için umutsuzca kullanmaya çalıştım 0..N. Teşekkürler!
Ingo Bürk

1
.slice(0,j)ondan daha kısa olan bir karakterdir .substr(0,j). Dahası, bir tamsayıya dönüştürmenin gereksiz görünmesi |0de kaldırılabilir ( |0aslında kullanılması , yöntemin kullanışlılığını azaltır çünkü 2 ^ 31'i aşan tekrarlar için başarısız olur).
Rob W


0

Java 8, 28 bayt

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

Çevrimiçi deneyin.

Açıklama:

İnput-String'in regex ile eşleşip eşleşmediğini denetler; burada tüm String ile String#matchesörtüşecek şekilde eklenir ^...$.
Regex'in kendisinin açıklaması:

^(s?)(.+)\1+$
^                Begin of the string
 (s?)            Enable DOTALL-mode, where `.` also matches new-lines
     (           Open capture group 1
      .+          One or more characters
        )        Close capture group 1
         \1+     Plus the match of the capture group 1, one or more times
            $    End of the string

Bu nedenle temel olarak bir alt dize iki veya daha fazla kez tekrar edilip edilmediğini kontrol eder (yeni satırları destekler).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.