String.prototype.isRepeat


41

CẬP NHẬT : đệ trình Pyth của isaacg là người chiến thắng!


Nhiều người trong số các bạn hẳn đã nghe nói rằng có một phiên bản JavaScript thú vị hơn trong thị trấn (đọc ES6) có một phương pháp String.prototype.repeatđể bạn có thể làm

"Hello, World!".repeat(3)

và lấy

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

là đầu ra.

Công việc của bạn là viết một hàm hoặc một chương trình bằng ngôn ngữ bạn chọn để phát hiện xem một chuỗi đã bị biến đổi như vậy chưa.

tức là chuỗi đầu vào có thể được biểu diễn dưới dạng nlặp lại thời gian chính xác của chuỗi nhỏ hơn. Đầu ra (như câu lệnh trả về của hàm hoặc STDOUT) phải là sự thật nếu chuỗi có thể hoặc sai nếu chuỗi không thể được biểu diễn dưới dạng lặp lại của chuỗi nhỏ hơn.

Một số mẫu đầu vào:

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

Lưu ý rằng đầu vào cuối cùng là sai, do đó nnên lớn hơn1

Hoàn thành quy tắc

  • Viết hàm / chương trình bằng bất kỳ ngôn ngữ nào để nhập (thông qua đối số hàm / dòng lệnh args / STDIN) một chuỗi
  • Trả về / In giá trị trung thực nếu chuỗi đã cho được hình thành thông qua sự lặp lại chính xác của chuỗi nhỏ hơn, lặp lại ít nhất hai lần.
  • Kích thước tối đa của chuỗi đầu vào là lý tưởng Infinity
  • Chuỗi có thể có tất cả các ký tự ASCII có thể
  • Đây là một để mã nhỏ nhất trong các ký tự thắng.

Cái gì "" - chuỗi rỗng - trả về? (Nó chứa vô số bản sao của chuỗi trống.)
billpg

@billpg giá trị giả
Tối ưu hóa

Bạn đang hòa vốn bằng phiếu bầu? Thực tế phổ biến là tôi nộp sớm hơn (tốt, người đầu tiên đã đánh golf xuống điểm số buộc). Nhưng tôi không chắc chắn điều đó được viết ra dưới dạng bộ ngắt kết nối mặc định ở bất cứ đâu, vì vậy cuối cùng nó tùy thuộc vào bạn.
Martin Ender

Thời gian giữa bài viết của họ chỉ 30 phút. Tôi sẽ không coi đó là đủ để chiến thắng :). Vì thời điểm đó sẽ không thay đổi ngay bây giờ, nhưng phiếu bầu có thể, tôi đã đi với phiếu bầu
Trình tối ưu hóa

Câu hỏi này nên được đổi tên thành xnor :) Anh ấy là người đàn ông!
Silviu Burcea

Câu trả lời:


16

Bình thường , 9

/:+zz1_1z

Hoặc là

}z:+zz1_1

Đây đều là những bản dịch gần gũi với câu trả lời python của @ xnor, ngoại trừ việc họ lấy đầu vào từ STDIN và in nó. Đầu tiên là tương đương với:

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

0 cho Sai, 1 cho Đúng.

Dòng thứ hai tương đương với:

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

Sai cho Sai, Đúng cho Đúng.

Trình biên dịch chính thức của Pyth có một lỗi liên quan đến cái thứ hai mà tôi vừa vá, vì vậy cái đầu tiên là bản chính thức của tôi.


Tôi chỉ tìm cách để thông báo cho bạn về lỗi đó (Boolean không được in). Không nghĩ đến lần đầu tiên và sử dụng xquá lâu ...
Dennis

Vâng, lỗi đã được sửa. Ngoài ra, nếu bạn muốn báo cáo lỗi, một cách tốt có thể là mở một sự cố trên trang web github, tại đây: github.com/isaacg1/pyth/issues
isaacg

Oh, nó được. Tôi không biết đường đi quanh GitHub và tôi không bao giờ chú ý đến bảng điều hướng bên phải ...
Dennis

81

Con trăn (24)

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

Kiểm tra xem chuỗi có phải là chuỗi con của chính nó được nối hai lần hay không, loại bỏ các ký tự đầu tiên và cuối cùng để tránh các kết quả tầm thường. Nếu có, nó phải là một hoán vị tuần hoàn không cần thiết của chính nó, và do đó tổng của các phân đoạn lặp lại.


8
Một bản dịch tầm thường sang Golfscript mang lại 10 ký tự:..+);(;\?)
Justin

3
Tôi không hiểu làm thế nào điều này hoạt động. Bạn có thể đưa ra một ví dụ được giải thích thủ công về cách điều này sẽ xử lý một chuỗi không?
Nzall

8
@NateKerkhofs lấy abcabc. s+sbiến nó thành abcabcabcabc. các [1:-1]mảnh của hai đầu để mang lại bcabcabcabcab. và sau đó s in ...cố gắng tìm abcabcnhư một chuỗi con của điều đó. Chuỗi con này không thể được tìm thấy ở một trong hai nửa ban đầu, vì cả hai đều được rút ngắn, vì vậy nó phải kéo dài cả hai nửa. Cụ thể, nó phải có kết thúc riêng trước khi bắt đầu, ngụ ý rằng nó phải được tạo thành từ các chất nền giống nhau (lặp đi lặp lại).
Martin Ender

6
Bạn cắt nó sau khi bạn nhân đôi nó. abtrở thành trở ababthành ba, vì vậy nó trả về false, trong khi aatrở aaaathành aa, trả về true.
lịch sử

1
@SargeBorsch Nó hoạt động giống nhau: qweqweqwetrong weqweqweqweqweqwTrue.
xnor

30

Regex (hương vị ECMAScript), 11 byte

Âm thanh như một công việc cho regex!

^([^]+)\1+$

Kiểm tra nó ở đây.

Tôi đã chọn ECMAScript, vì đó là hương vị duy nhất (tôi biết) [^]phù hợp với bất kỳ nhân vật nào. Trong tất cả những người khác, tôi cần một lá cờ để thay đổi hành vi .hoặc sử dụng [\s\S]dài hơn ba ký tự.

Tùy thuộc vào cách chúng ta đang đếm lá cờ, mà có thể tất nhiên là một byte ngắn hơn. Ví dụ: nếu chúng ta đang đếm mẫu + cờ (ví dụ: bỏ qua dấu phân cách), tương đương PCRE / Perl sẽ là

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

Đó là 10 byte, bỏ qua các dấu phân cách.

Kiểm tra nó ở đây.

Điều này chỉ khớp với các chuỗi bao gồm ít nhất hai lần lặp lại của một số chuỗi con.

Đây là một hàm ES6 26 byte đầy đủ, nhưng tôi duy trì rằng các lần gửi biểu thức chính quy thường có hiệu lực:

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

^(.+)\1+$làm việc cho tôi, đó là 9 byte. Nó không làm việc cho bạn?
Tối ưu hóa

@Optimizer Hãy thử một chuỗi có ngắt dòng.
Martin Ender

Tôi đã thử asd\nasd\nasd\n. Nó hoạt động
Tối ưu hóa

@Optimizer refiddle.com/refiddles/5417fb2475622d4df7e70a00 dường như không hoạt động đối với tôi (và không nên)
Martin Ender

Yup, điều đó không làm việc. Có lẽ nó thoát được \ khi tôi viết \nthủ công
Trình tối ưu hóa

12

CJam, 9

q__+)@+#)

Tương tự như ý tưởng của 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 bắt buộc phải nâng cao điều này trước câu trả lời của riêng tôi về CJam
Chấn thương kỹ thuật số

Tại sao cần đến trận chung kết )? Tôi nghĩ thật hợp lý khi có -1 nghĩa là FALSE và> = 0 có nghĩa là THẬT
Chấn thương kỹ thuật số

@DigitalTrauma Tôi nghĩ 0 là giả mạo trong CJam ... cho các nhà khai thác thích g?.
jimmy23013

@DigitalTrauma: Việc cuối cùng có cần hay không phụ thuộc vào OP, nhưng nói đúng ra chỉ có 0 được coi là giả mạo trong CJam.
Dennis

@ user23013 @Dennis Nhưng còn #toán tử find thì sao? Chắc chắn kết quả của điều đó cũng là "sự thật" từ quan điểm thành công và thất bại?
Chấn thương kỹ thuật số

7

APL, 11

2<+/x⍷,⍨x←⍞

Giải thích
lấy đầu vào chuỗi từ màn hình
x←gán cho biến x
,⍨nối chuỗi với chính
x⍷tìm kiếm xtrong chuỗi kết quả. Trả về một mảng bao gồm 1 'ở vị trí bắt đầu của trận đấu và 0 ở nơi khác.
+/tính tổng
2<kiểm tra mảng nếu tổng lớn hơn 2 (vì sẽ có 2 kết quả không quan trọng)


7

CJam, 10 byte

Tôi bắt gặp lỗi của CJam. Câu trả lời đầu tiên của tôi, vì vậy có lẽ có thể được đánh gôn thêm:

q__+(;);\#

Đầu ra -1 cho FALSE và số> = 0 cho TRUE


5
Chào mừng đến với câu lạc bộ!
Dennis

5

GolfScript, 10 byte

..+(;);\?)

Một cách thực hiện ý tưởng thông minh khác của xnor.


Hahaha, tôi vừa đăng bài này một phút trước: codegolf.stackexchange.com/questions/37851/ . Tôi nghĩ về việc đăng nó như một câu trả lời, nhưng tôi nghĩ rằng các bản dịch tầm thường là không thú vị.
Justin

Tôi thậm chí đã kiểm tra câu trả lời mới lần này, nhưng không nhận xét mới ... Mã của bạn bị thiếu )mặc dù; khi không khớp, nó sẽ in -1. Nếu bạn định đăng nó như một câu trả lời, tôi sẽ sẵn sàng xóa tôi.
Dennis

Tôi đã thêm )ngay trước khi bạn đăng câu trả lời của bạn (Tôi đã chỉnh sửa nhận xét)
Justin

1
Phiên bản cải tiến (trong CJam) : q__+)@+#). Nó không hoạt động trong GolfScript.
jimmy23013

1
@ user23013: Không phải lần nữa. Tôi chỉ định đăng nó! Hiện tại có quá nhiều CJammers ngoài kia ...: P
Dennis

3

Con trăn - 59 57

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

3

Bash tinh khiết, 30 byte

Cổng đơn giản của câu trả lời thông minh của @ xnor :

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

Mã thoát là 0 cho TRUE và 1 cho 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
$ 

Lưu ý =~bên trong [[ ... ]]toán tử regex trong bash . Tuy nhiên "Bất kỳ phần nào của mẫu có thể được trích dẫn để buộc nó phải khớp với dạng chuỗi" . Vì vậy, như mọi người thường gặp với bash, việc trích dẫn đúng là rất quan trọng - ở đây chúng tôi chỉ muốn kiểm tra một chuỗi con và không phải là một kết hợp regex.


3

TI-CƠ BẢN - 32

Tôi nghĩ tôi sẽ thử một ngôn ngữ tokenized. Chạy với chuỗi trong Ans, trả về 0 nếu sai và độ dài của chuỗi lặp lại nếu đúng.

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

Thật ngạc nhiên khi nó là một lớp lót.


Nhưng ... nhưng ... tôi sẽ sử dụng TI-BASIC: P +1
Timtech

@Timtech Vâng, lưu ý cho bất kỳ ai đang thử thao tác chuỗi trong TI-BASIC: Đừng thử thao tác chuỗi trong TI-BASIC. : P Thật khó để thực hiện và tối ưu hóa.
Josiah Winslow

Ý tưởng tốt. Thao tác chuỗi là một trong những điều khó nhất để làm. Tuy nhiên, tôi đã đăng một số câu trả lời như thế này, vì vậy tôi đoán bây giờ bạn có một đối thủ cạnh tranh;)
Timtech

Mang nó vào! : P
Josiah Winslow

3

Bản thảo 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

Chắc chắn đây là giải pháp hợp lệ duy nhất? Ví dụ: từ (chuỗi) nanakhông nhất thiết phải được tạo từ"na".repeat(2)


"nana"không, nhưng câu hỏi không phải là kiểm tra xem .repeatđã được sử dụng hay chưa. Thay vào đó, cho dù chuỗi có lặp lại hay không
Trình tối ưu hóa

Tôi biết, tôi chỉ cố gắng trở thành một người thông minh: P
Mardoxx

2

Bản thảo 6 (34 36 )

Một câu trả lời ES6 khác, nhưng không sử dụng repeatvà sử dụng thủ thuật của xnor :

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

Phải được chạy trong bảng điều khiển của trình duyệt có khả năng ES6 như Firefox.


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

Hóa ra nó khá dài nhưng các chức năng bên ngoài luôn như vậy. Tôi nghĩ rằng tôi có thể viết lại mọi hàm chuỗi thay thế chúng bằng một vòng lặp hoặc một đệ quy. Nhưng theo kinh nghiệm của tôi, nó sẽ dài ra và thật lòng tôi không muốn thử.

Sau một số nghiên cứu, tôi thấy các giải pháp về hiệu suất cao nhưng không thông minh (và ngắn) như của xnor. chỉ để là bản gốc ... tôi viết lại cùng một ý tưởng trong c.

giải trình:

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

Bản thảo 6 (59 62 67 73 )

Không phải là người chiến thắng, nhưng có vẻ như ít nhất phải có một câu trả lời thực sự trong ES6 cho câu hỏi này thực sự sử dụng repeatchức năng:

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

Phải được chạy trong bảng điều khiển của trình duyệt có khả năng ES6 như Firefox.

Nó thực hiện rất nhiều lần lặp lại không cần thiết, nhưng tại sao làm cho nó dài hơn chỉ để tránh điều đó, phải không?

  • Chỉnh sửa # 1: Đã lưu một vài byte bằng cách chuyển đổi nó thành một hàm. Cảm ơn Trình tối ưu hóa!
  • Chỉnh sửa # 2: Nhờ hsl cho thủ thuật toán tử trải rộng để tiết kiệm nhiều byte hơn!
  • Chỉnh sửa # 3: Và cảm ơn Rob W. cho 3 byte khác!

Bạn chỉ có thể chuyển đổi nó thành một chức năng để lưu nhiều byte hơn ở đó
Trình tối ưu hóa

@Optimizer Đúng, tôi đoán nó không phải là "stdin". Cuộc sống của bạn đúng với tên của bạn :)
Ingo Bürk

Tôi đã không kiểm tra này, nhưng bạn sẽ có thể sử dụng các toán tử lây lan cho [...i]thay vìi.split('')
NinjaBearMonkey

1
@hsl Điên, mà hoạt động. Tôi không biết toán tử lây lan hoạt động như thế. Ban đầu tôi rất cố gắng sử dụng nó để tạo ra một mảng với phạm vi 0..N. Cảm ơn!
Ingo Bürk

1
.slice(0,j)là một ký tự ngắn hơn .substr(0,j). Hơn nữa, việc chuyển đổi thành một số nguyên dường như không cần thiết |0có thể được loại bỏ (sử dụng |0thực sự làm giảm tính hữu ích của phương thức vì nó sẽ thất bại đối với các lần lặp lại vượt quá 2 ^ 31).
Rob W


0

Java 8, 28 byte

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

Hãy thử trực tuyến.

Giải trình:

Kiểm tra xem Chuỗi đầu vào có khớp với biểu thức chính quy hay không, trong đó String#matchesthêm vào ^...$để khớp với toàn bộ Chuỗi.
Giải thích về chính 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

Vì vậy, về cơ bản nó sẽ kiểm tra nếu một chuỗi con được lặp lại hai lần trở lên (hỗ trợ các dòng mới).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.