String.prototype.isRepeated


41

อัพเดท : การส่ง Pyth ของ isaacgเป็นผู้ชนะ!


หลายคนคงเคยได้ยินว่ามี JavaScript รุ่นเย็นในเมือง (อ่าน ES6) ซึ่งมีวิธีการString.prototype.repeatเพื่อให้คุณสามารถทำ

"Hello, World!".repeat(3)

และรับ

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

เป็นเอาท์พุท

งานของคุณคือการเขียนฟังก์ชั่นหรือโปรแกรมในภาษาที่คุณเลือกซึ่งตรวจพบว่าสตริงได้รับภายใต้การเปลี่ยนแปลงดังกล่าว

เช่นสตริงอินพุตสามารถแสดงเป็นการnซ้ำซ้อนเวลาที่แน่นอนของสตริงที่เล็กกว่า เอาท์พุท (เป็นคำสั่งส่งกลับของฟังก์ชั่นหรือ STDOUT) ควรเป็นจริงถ้าสตริงสามารถหรือเท็จถ้าสตริงไม่สามารถแสดงเป็นซ้ำของสตริงที่มีขนาดเล็กลง

ตัวอย่างอินพุตบางส่วน:

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

โปรดทราบว่าการป้อนข้อมูลครั้งสุดท้ายเป็นเท็จจึงnควรมากกว่า1

ทำตามกฎ

  • เขียนฟังก์ชั่น / โปรแกรมในภาษาใด ๆ เพื่อป้อนข้อมูล (ผ่านฟังก์ชั่นอาร์กิวเมนต์ / บรรทัดคำสั่ง args / STDIN) สตริง
  • ส่งคืน / พิมพ์ค่าความจริงหากสตริงที่กำหนดเกิดขึ้นผ่านการซ้ำซ้อนที่แน่นอนของสตริงที่เล็กกว่าทำซ้ำอย่างน้อยสองครั้ง
  • ขนาดสูงสุดของสายป้อนข้อมูลเป็นแบบอินฟินิตี้
  • สตริงสามารถมีอักขระ ASCII ที่เป็นไปได้ทั้งหมด
  • นี่คือซึ่งเป็นเล็กที่สุดในตัวละครที่ชนะ

"" - สตริงว่าง - ควรส่งคืนอย่างไร (มันมีจำนวนสำเนาของสตริงที่ไม่มีที่สิ้นสุด)
billpg


คุณผูกด้วยคะแนนโหวต? การปฏิบัติทั่วไปคือการส่งก่อนหน้านี้ฉันคิดว่า (ดีคนแรกที่ได้กอล์ฟลงไปที่คะแนนคาด) แต่ฉันไม่แน่ใจว่ามันถูกเขียนเป็นตัวถอดรหัสเริ่มต้นที่ใดก็ได้ดังนั้นในที่สุดมันก็ขึ้นอยู่กับคุณ
Martin Ender

เวลาระหว่างการโพสต์ของพวกเขาเพียง 30 นาที ฉันจะไม่พิจารณาว่าจะเพียงพอสำหรับการชนะ :) ตั้งแต่เวลานั้นจะไม่เปลี่ยนแปลงในขณะนี้ แต่การลงคะแนนสามารถฉันไปด้วยคะแนน
เครื่องมือเพิ่มประสิทธิภาพ

คำถามนี้ควรเปลี่ยนชื่อเป็น xnor :) เขาเป็นผู้ชาย!
Silviu Burcea

คำตอบ:


16

Pyth , 9

/:+zz1_1z

หรือ

}z:+zz1_1

เหล่านี้เป็นทั้งการแปลอย่างใกล้ชิดของคำตอบหลามของ @ xnor ยกเว้นว่าพวกเขารับอินพุตจาก STDIN และพิมพ์ ครั้งแรกเทียบเท่ากับ:

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

0 สำหรับเท็จ 1 สำหรับจริง

บรรทัดที่สองเทียบเท่ากับ:

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

เท็จสำหรับเท็จจริงสำหรับจริง

คอมไพเลอร์อย่างเป็นทางการของ Pyth มีข้อผิดพลาดเกี่ยวกับอันที่สองซึ่งฉันเพิ่งแก้ไขดังนั้นอันแรกคือการส่งอย่างเป็นทางการของฉัน


ฉันแค่ค้นหาวิธีที่จะแจ้งให้คุณทราบเกี่ยวกับข้อผิดพลาดนั้น (บูลีนไม่ได้รับการพิมพ์) ไม่ได้คิดว่าในครั้งแรกและการใช้xเป็นเวลานานเกินไป ...
เดนนิส

ใช่ข้อผิดพลาดได้รับการแก้ไขแล้ว นอกจากนี้หากคุณต้องการรายงานข้อผิดพลาดวิธีที่ดีอาจเป็นการเปิดปัญหาในไซต์ github ได้ที่นี่: github.com/isaacg1/pyth/issues
isaacg

โอ้มีมันเป็น ฉันไม่ทราบวิธีการของฉันรอบ GitHub และฉันไม่เคยสังเกตเห็นแผงนำทางด้านขวา ...
Dennis

81

Python (24)

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

ตรวจสอบว่าสตริงนั้นเป็นสตริงย่อยของตัวเองต่อกันสองครั้งหรือไม่และกำจัดอักขระตัวแรกและตัวสุดท้ายเพื่อหลีกเลี่ยงการจับคู่เล็กน้อย หากเป็นเช่นนั้นจะต้องเป็นการเปลี่ยนรูปแบบวัฏจักรของตัวเองใหม่และรวมเป็นกลุ่มซ้ำ


8
คำแปลเล็กน้อยใน Golfscript ให้ผล 10 ตัวอักษร:..+);(;\?)
Justin

3
ฉันไม่เข้าใจวิธีการทำงาน คุณสามารถยกตัวอย่างที่อธิบายด้วยตนเองว่าจะจัดการสตริงได้อย่างไร
Nzall

8
@NateKerkhofs abcabcใช้ เปลี่ยนมันเป็นs+s สับของปลายทั้งสองข้างให้ผลผลิต แล้วพยายามค้นหาเป็นสตริงย่อยของสิ่งนั้น ไม่พบสตริงย่อยนี้ในครึ่งหนึ่งของต้นฉบับเนื่องจากทั้งคู่ถูกทำให้สั้นลงดังนั้นจึงต้องขยายทั้งสองครึ่ง โดยเฉพาะอย่างยิ่งมันจะต้องมีจุดสิ้นสุดของตัวเองก่อนที่จะเริ่มต้นซึ่งหมายความว่ามันจะต้องประกอบด้วยสตริงย่อย (ซ้ำ) เหมือนกัน abcabcabcabc[1:-1]bcabcabcabcabs in ...abcabc
Martin Ender

6
คุณสับมันหลังจากที่คุณเพิ่มเป็นสองเท่า abกลายababเป็นbaดังนั้นมันกลับเท็จในขณะที่aaกลายaaaaเป็นaaซึ่งผลตอบแทนที่แท้จริง
ฮิสโทแคต

1
@SargeBorsch การทำงานก็เหมือนกัน: qweqweqweในเป็นweqweqweqweqweqw True
xnor

30

Regex (ECMAScript รส), 11 ไบต์

ดูเหมือนงาน regex!

^([^]+)\1+$

ทดสอบที่นี่

ฉันเลือก ECMAScript เพราะเป็นเพียงรสชาติ (ฉันรู้) ที่[^]ตรงกับตัวละครใด ๆ ในคนอื่น ๆ ฉันต้องการธงเพื่อเปลี่ยนพฤติกรรม.หรือใช้[\s\S]ซึ่งมีความยาวสามอักขระ

ขึ้นอยู่กับว่าเรานับธงอย่างไรนั้นอาจเป็นไบต์ที่สั้นกว่า เช่นถ้าเรานับรูปแบบ + ธง (เช่นไม่สนใจตัวคั่น) ค่าเทียบเท่า PCRE / Perl จะเป็น

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

ซึ่งคือ 10 ไบต์โดยไม่สนใจตัวคั่น

ทดสอบที่นี่

สิ่งนี้ตรงกับสตริงเท่านั้นซึ่งประกอบด้วยการซ้ำอย่างน้อยสองครั้งของสตริงย่อยบางส่วน

นี่คือฟังก์ชั่นเต็มรูปแบบ 26 ไบต์ ES6 แต่ฉันยืนยันว่าการส่งนิพจน์ทั่วไปนั้นใช้ได้จริง:

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

^(.+)\1+$ใช้งานได้สำหรับฉันซึ่งมีขนาด 9 ไบต์ มันไม่ทำงานสำหรับคุณ
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer ลองใช้สตริงที่มีตัวแบ่งบรรทัด
Martin Ender

ฉันพยายามasd\nasd\nasd\nแล้ว ใช้งานได้
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer refiddle.com/refiddles/5417fb2475622d4df7e70a00ดูเหมือนจะไม่ทำงานสำหรับฉัน (และไม่ควรทำ)
Martin Ender

ใช่นั่นไม่ได้ อาจหนี\ เมื่อฉันเขียน\nด้วยตนเอง
เครื่องมือเพิ่มประสิทธิภาพ

12

CJam, 9

q__+)@+#)

คล้ายกับแนวคิดของ xnor

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. ";

+1 จำเป็นต้องถอนรากถอนโคน
Digital Trauma

ทำไมความจำเป็นในการสุดท้าย)? ฉันคิดว่ามันสมเหตุสมผลที่จะมี -1 หมายถึง FALSE และ> = 0 หมายถึง TRUE
Digital Trauma

@DigitalTrauma ผมคิดว่าเป็น 0 falsy ใน CJam ... สำหรับผู้ประกอบการเช่นและg ?
jimmy23013

@ DigitalTrauma: ไม่ว่าจะเป็นความต้องการในท้ายที่สุดขึ้นอยู่กับ OP แต่พูดอย่างเคร่งครัดเพียงศูนย์ถือเป็นเท็จใน CJam
เดนนิส

@ user23013 @Dennis แต่#ผู้ดำเนินการค้นหาล่ะ แน่นอนว่าผลลัพธ์ที่ได้คือ "ความจริง" จากมุมมองความสำเร็จกับความล้มเหลว?
Digital Trauma

7

APL, 11

2<+/x⍷,⍨x←⍞

คำอธิบาย
รับอินพุตสตริงจากหน้าจอที่
x←กำหนดให้กับตัวแปรx
,⍨เชื่อมสตริงด้วยตัวเอง
x⍷ค้นหาxในสตริงผลลัพธ์ ส่งกลับอาร์เรย์ที่ประกอบด้วย 1 ในตำแหน่งเริ่มต้นของการแข่งขันและ 0 ของที่อื่น
+/สรุปผลการ
2<ตรวจสอบอาร์เรย์ว่าผลรวมมากกว่า 2 (เนื่องจากจะมีการแข่งขัน 2 เรื่องเล็กน้อย)


7

CJam, 10 ไบต์

ฉันจับข้อผิดพลาด CJam คำตอบแรกของฉันดังนั้นอาจจะสามารถเล่นกอล์ฟได้อีก:

q__+(;);\#

เอาต์พุต -1 สำหรับ FALSE และตัวเลข> = 0 สำหรับ TRUE


5
ยินดีต้อนรับสู่คลับ!
เดนนิส

5

GolfScript ขนาด 10 ไบต์

..+(;);\?)

อีกหนึ่งการดำเนินการตามแนวคิดที่ชาญฉลาดของ xnor


ฮ่า ๆ ๆ ๆ ผมเพิ่งโพสต์นี้นาทีที่ผ่านมา: codegolf.stackexchange.com/questions/37851/... ฉันคิดถึงการโพสต์มันเป็นคำตอบ แต่ฉันคิดว่าการแปลเล็กน้อยไม่น่าสนใจ
Justin

ฉันได้ตรวจสอบหาคำตอบใหม่ในเวลานี้ แต่ไม่ใช่สำหรับความคิดเห็นใหม่ ... รหัสของคุณหายไป)แม้ว่า; -1เมื่อมีไม่ตรงก็จะพิมพ์ หากคุณกำลังจะโพสต์ว่าเป็นคำตอบฉันยินดีที่จะลบของฉัน
เดนนิส

ฉันเพิ่ม)เพียงก่อนที่คุณโพสต์คำตอบของคุณ (ฉันแก้ไขความคิดเห็น)
จัสติน

1
รุ่นปรับปรุง (ใน q__+)@+#)CJam): มันไม่ทำงานใน GolfScript
jimmy23013

1
@ user23013: ไม่อีกแล้ว ฉันเพิ่งจะโพสต์นั้น! ตอนนี้มี CJammers มากเกินไป ... : P
Dennis


3

ทุบตีบริสุทธิ์ 30 ไบต์

พอร์ตที่เรียบง่ายของคำตอบที่ฉลาดของ@ xnor :

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

รหัสทางออกคือ 0 สำหรับ TRUE และ 1 สำหรับ FALSE:

$ 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
$ 

หมายเหตุ=~ภายใน[[ ... ]]เป็นผู้ประกอบการใน regex ทุบตี อย่างไรก็ตาม"ส่วนหนึ่งของรูปแบบใด ๆ อาจจะยกมาเพื่อบังคับให้มีการจับคู่เป็นสตริง" ดังนั้นบ่อยครั้งที่ ai ใช้ bash การได้รับข้อความที่ถูกต้องนั้นสำคัญมาก - ที่นี่เราแค่ต้องการตรวจสอบการส่งสตริงและไม่ใช่ regex


3

TI-BASIC - 32

ฉันคิดว่าฉันลองใช้ภาษาที่ได้รับโทเค็น รันด้วยสตริงใน Ans ส่งคืนค่า 0 หากเป็นเท็จและความยาวของสตริงซ้ำถ้าเป็นจริง

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

มันช่างน่าทึ่งแค่ไหน


แต่ ... แต่ ... ฉันจะใช้ TI-BASIC: P +1
Timtech

@ Timtech โปรดทราบว่าทุกคนที่พยายามจัดการสตริงใน TI-BASIC: อย่าพยายามจัดการสตริงใน TI-BASIC : P นั่นเป็นเรื่องยากที่จะสร้างและเพิ่มประสิทธิภาพ
โยสิยาห์พระพุทธเจ้าทรงพระพุทธเจ้า

ความคิดที่ดี. การจัดการสตริงเป็นหนึ่งในสิ่งที่ยากที่สุดที่จะทำ อย่างไรก็ตามฉันได้โพสต์คำตอบหลายอย่างเช่นนี้ดังนั้นฉันเดาว่าตอนนี้คุณมีคู่แข่งแล้ว)
Timtech

นำมาไว้บน! : 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

แน่นอนนี่เป็นทางออกที่ถูกต้องเท่านั้น? ตัวอย่างเช่นnanaไม่จำเป็นต้องสร้างคำ (สตริง)"na".repeat(2)


"nana"ไม่ใช่ แต่คำถามนั้นไม่ได้ทดสอบว่า.repeatมีการใช้หรือไม่ ค่อนข้างจะเป็นว่าสตริงนั้นซ้ำแล้วซ้ำอีกหรือไม่
เครื่องมือเพิ่มประสิทธิภาพ

ฉันรู้ว่าฉันแค่พยายามเป็นสมาร์ท - ลา: P
Mardoxx


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;}

มันค่อนข้างยาว แต่ฟังก์ชั่นภายนอกก็เป็นแบบนั้นเสมอ มันอยู่ในใจของฉันที่ฉันสามารถเขียนใหม่ทุกฟังก์ชั่นสตริงแทนที่พวกเขาด้วยการวนซ้ำหรือซ้ำ แต่จากประสบการณ์ของฉันมันจะเปิดออกอีกต่อไปและตรงไปตรงมาฉันไม่ต้องการลอง

หลังจากการวิจัยบางอย่างฉันเห็นวิธีการแก้ปัญหาที่มีประสิทธิภาพสูง แต่ไม่ฉลาด (และสั้น) เท่า xnor เพียงเพื่อเป็นต้นฉบับ ... ฉันเขียนความคิดเดียวกันในค

คำอธิบาย:

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 )

ไม่ใช่ผู้ชนะ แต่ดูเหมือนว่าควรมีคำตอบอย่างน้อยหนึ่งคำตอบใน ES6 สำหรับคำถามนี้ที่ใช้repeatฟังก์ชันจริง:

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

ต้องทำงานในคอนโซลของเบราว์เซอร์ที่สามารถใช้ ES6 เช่น Firefox

มันทำซ้ำที่ไม่จำเป็นจำนวนมาก แต่ทำไมต้องทำให้นานขึ้นเพื่อหลีกเลี่ยงสิ่งนั้นใช่ไหม

  • แก้ไข # 1:บันทึกสองสามไบต์โดยแปลงเป็นฟังก์ชัน ขอบคุณเครื่องมือเพิ่มประสิทธิภาพ!
  • แก้ไข # 2:ขอบคุณ hsl สำหรับเคล็ดลับการแพร่กระจายตัวดำเนินการเพื่อบันทึกไบต์เพิ่มเติม!
  • แก้ไข # 3:และต้องขอบคุณ Rob W. อีก 3 ไบต์!

คุณสามารถแปลงเป็นฟังก์ชั่นเพื่อประหยัดไบต์ได้มากขึ้น
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer จริงฉันเดาว่ามันไม่จำเป็นต้องเป็น "stdin" ชีวิตคุณขึ้นอยู่กับชื่อของคุณ :)
Ingo Bürk

ฉันไม่ได้ทดสอบนี้ แต่คุณควรจะสามารถที่จะใช้ประกอบการแพร่กระจายสำหรับ[...i]แทนi.split('')
NinjaBearMonkey

1
@hsl Crazy ที่ใช้งานได้ ฉันไม่ทราบว่าผู้ดำเนินการแพร่กระจายทำงานเช่นนั้น 0..Nเดิมผมหมดความพยายามที่จะใช้มันเพื่อสร้างอาร์เรย์ที่มีช่วง ๆ ขอบคุณ!
Ingo Bürk

1
.slice(0,j).substr(0,j)เป็นหนึ่งในตัวละครที่สั้นกว่า นอกจากนี้การแปลงเป็นจำนวนเต็มดูเหมือนไม่จำเป็น|0สามารถลบออกได้ (การใช้|0จริงช่วยลดประโยชน์ของวิธีการเพราะมันจะล้มเหลวสำหรับการทำซ้ำที่เกิน 2 ^ 31)
Rob W


0

Java 8, 28 ไบต์

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

ลองออนไลน์

คำอธิบาย:

ตรวจสอบว่า Input-String ตรงกับ regex หรือไม่String#matchesโดยที่เพิ่ม^...$เข้ากับ String ทั้งหมดโดยปริยาย
คำอธิบายของ regex นั้น:

^(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

ดังนั้นโดยทั่วไปจะตรวจสอบว่าซับสตริงซ้ำสองครั้งหรือมากกว่า (รองรับบรรทัดใหม่)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.