String.prototype.isRepeated


41

업데이트 : isaacg의 Pyth 제출 이 승자입니다!


여러분의 많은 방법을 가지고 마을 (ES6를 읽기)에서 자바 스크립트의 쿨러 버전이 들었해야합니다 String.prototype.repeat당신이 할 수 있도록이

"Hello, World!".repeat(3)

그리고 얻다

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

출력으로.

당신의 임무는 문자열이 그러한 변형을 겪었는지 감지하는 선택한 언어로 함수 또는 프로그램을 작성하는 것 입니다.

즉, 입력 문자열은 n더 작은 문자열 의 정확한 시간 반복 으로 표시 될 수 있습니다 . 문자열이 더 작은 문자열의 반복으로 표시 될 수없는 경우 문자열이 가능하거나 거짓 인 경우 출력 (함수의 return 문 또는 STDOUT)이 진실이어야합니다.

일부 샘플 입력 :

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

주 마지막 입력 오류가 있는지, 따라서 n보다 커야1

완전한 규칙

  • 문자열을 입력 할 함수 / 프로그램을 모든 언어로 작성하십시오 (함수 인수 / 명령 줄 인수 / STDIN을 통해).
  • 주어진 문자열이 작은 문자열의 정확한 반복을 통해 형성되고 적어도 두 번 반복되면 진실한 값을 반환 / 인쇄합니다.
  • 입력 문자열의 최대 크기는 무한대입니다.
  • 문자열은 가능한 모든 ASCII 문자를 가질 수 있습니다
  • 이것은 이므로 문자가 가장 작은 코드가 승리합니다.

""-빈 문자열-무엇을 반환해야합니까? (빈 문자열의 사본은 무한정 포함되어 있습니다.)
billpg

@billpg falsy value
Optimizer

당신은 투표로 동점입니까? 일반적인 관행은 내가 생각하기에 초기에 제출하는 것입니다. 그러나 이것이 기본 타이 브레이커로 기록되어 있는지 확실하지 않으므로 궁극적으로 귀하에게 달려 있습니다.
Martin Ender

게시 사이의 시간은 30 분입니다. 나는 그것을 이기기에 충분하다고 생각하지 않을 것이다 :). 그때는 바뀌지 않았지만 투표 할 수 있기 때문에 투표했습니다.
Optimizer

이 질문은 xnor로 이름을 바꿔야합니다. :) 그는 사람입니다!
Silviu Burcea

답변:


16

피스 , 9

/:+zz1_1z

또는

}z:+zz1_1

이들은 모두 STDIN에서 입력을 받아 인쇄하는 것을 제외하고 @xnor의 python answer의 밀접한 번역입니다. 첫 번째는 다음과 같습니다.

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

False의 경우 0, True의 경우 1

두 번째 줄은 다음과 같습니다.

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

False는 False, True는 True입니다.

Pyth의 공식 컴파일러에는 방금 패치 한 두 번째 버그와 관련된 버그가 있었으므로 첫 번째는 공식 제출입니다.


방금 그 버그에 대해 알려주는 방법을 찾고있었습니다 (부울이 인쇄되지 않음). 처음 생각하지 않았고 사용 시간 x이 너무 길었습니다 ...
Dennis

네, 버그가 수정되었습니다. : 당신이 버그를 신고하려는 경우 또한, 좋은 방법은 github의 사이트에서 문제를 열 수 있습니다 github.com/isaacg1/pyth/issues
isaacg

아, 그렇습니다 . 나는 GitHub를 돌아 보는 길을 모른다. 그리고 오른쪽에있는 탐색 패널을 본 적이 없다.
Dennis

81

파이썬 (24)

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

문자열이 자체의 하위 문자열인지 두 번 연결되어 있는지 확인하여 사소한 일치를 피하기 위해 첫 번째 문자와 마지막 문자를 제거합니다. 이 경우 자체의 사소한 순환 순열과 반복 세그먼트의 합이어야합니다.


8
Golfscript 로의 간단한 번역으로 10 개의 문자가 생성됩니다...+);(;\?)
Justin Justin

3
이것이 어떻게 작동하는지 잘 모르겠습니다. 이것이 문자열을 처리하는 방법에 대한 수동 설명 예제를 제공 할 수 있습니까?
Nzall

8
@NateKerkhofs가 걸립니다 abcabc. s+s로 바뀝니다 abcabcabcabc. [1:-1]양 끝 의 갈비는 양보 bcabcabcabcab합니다. 그런 다음 하위 문자열 s in ...로 찾으려고 abcabc합니다. 이 부분 문자열은 원래 절반에서 찾을 수 없습니다. 둘 다 짧아 졌으므로 두 부분 모두에 걸쳐 있어야합니다. 특히, 시작하기 전에 고유 한 끝이 있어야합니다. 이는 동일한 (반복되는) 서브 스트링으로 구성되어야 함을 의미합니다.
Martin Ender

6
당신은 그것을 두 배로 잘라. ab하게 abab된다 bafalse를 반환 있도록하면서, aa하게 aaaa된다 aatrue를 반환한다.
histocrat

1
@SargeBorsch 그것은 동일하게 작동합니다 : qweqweqwein weqweqweqweqweqwis True.
xnor

30

정규식 (ECMAScript 맛), 11 바이트

정규식에 대한 직업처럼 들립니다!

^([^]+)\1+$

여기에서 테스트하십시오.

나는 [^]어떤 문자와도 일치 하는 유일한 맛이기 때문에 ECMAScript를 선택했습니다 . 다른 모든 경우에는 동작을 변경 .하거나 [\s\S]3 자보다 긴 플래그를 사용해야 합니다.

우리가 플래그를 계산하는 방법에 따라 그 물론 바이트 짧아. 예를 들어 패턴 + 플래그 (예 : 구분 기호 무시)를 세는 경우 PCRE / Perl에 해당하는 값은

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

구분자를 무시하고 10 바이트입니다.

여기에서 테스트하십시오.

이것은 일부 하위 문자열을 두 번 이상 반복하여 구성한 문자열 만 일치합니다.

다음은 전체 26 바이트 ES6 함수이지만 정규 표현식 제출은 일반적으로 유효합니다.

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

^(.+)\1+$9 바이트 인 나를 위해 일합니다. 그것은 당신을 위해 작동하지 않습니까?
Optimizer

@Optimizer 줄 바꿈이있는 문자열을 사용해보십시오.
Martin Ender

나는 노력했다 asd\nasd\nasd\n. 작동
Optimizer

@Optimizer의 refiddle.com/refiddles/5417fb2475622d4df7e70a00은 나를 위해 작동하지 않는 것 (그리고 안)
마틴 청산

네, 작동하지 않습니다. 아마 수동으로 \ 쓸 때 벗어날 수도 \n있습니다
Optimizer

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은 FALSE,> = 0은 TRUE를 갖는 것이 합리적이라고 생각합니다
Digital Trauma

@DigitalTrauma 나는 공 같은 사업자 ... CJam에서 falsy 생각 g하고 ?.
jimmy23013

@DigitalTrauma : 필요 여부는 궁극적으로 OP에 달려 있지만 CJam에서는 엄격하게 0 만 말하는 것은 허위로 간주됩니다.
Dennis

@ user23013 @Dennis하지만 #찾기 연산자는 어떻습니까? 성공의 결과와 실패의 관점에서 분명히 그 결과가 "더러운"것입니까?
디지털 외상

7

APL, 11

2<+/x⍷,⍨x←⍞

설명
은 화면에서 문자열 입력
x←을 변수에 지정 x
,⍨하여 문자열을
x⍷검색 x하여 결과 문자열에서 문자열을 연결 합니다. 일치하는 시작 위치에서 1로, 다른 곳에서는 0으로 구성된 배열을 반환합니다.
+/
2<이 2보다 큰 경우 배열 검사를 합합니다 (2 개의 사소한 일치가 있으므로).


7

CJam, 10 바이트

CJam 버그를 발견했습니다. 내 첫 대답은 아마 더 골프를 칠 수 있습니다.

q__+(;);\#

FALSE의 경우 -1을 출력하고 TRUE의 경우> 0을 출력합니다.


5
클럽에 오신 것을 환영합니다!
Dennis

5

GolfScript, 10 바이트

..+(;);\?)

xnor의 영리한 아이디어의 또 다른 구현.


하하, 방금 전에 이것을 codegolf.stackexchange.com/questions/37851/… 게시했습니다 . 나는 그것을 답변으로 게시하는 것에 대해 생각했지만 사소한 번역은 흥미가 없다고 생각했습니다.
저스틴

나는 심지어 이번에는 새로운 답변을 확인했지만 새로운 의견은 확인하지 않았습니다 ... 코드가 누락되었습니다 ). 일치하지 않으면 인쇄 -1됩니다. 답변으로 게시하려고한다면 기꺼이 삭제하겠습니다.
Dennis

)답변을 게시하기 직전에 추가했습니다 (댓글을 편집했습니다)
Justin

1
개선 된 버전 (CJam) : q__+)@+#). GolfScript에서는 작동하지 않습니다.
jimmy23013

1
@ user23013 : 다시는 아닙니다. 나는 단지 그것을 게시하려고했다! 지금까지 너무 많은 CJammer가 있습니다 ... : P
Dennis

3

파이썬 -59 57

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

3

순수한 bash, 30 바이트

@xnor의 영리한 답변의 간단한 포트 :

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

종료 코드는 TRUE의 경우 0이고 FALSE의 경우 1입니다.

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

참고 =~내는 [[ ... ]]것입니다 떠들썩한 파티에서 정규식 연산자 . 그러나 "패턴의 일부는 따옴표로 묶어 문자열로 일치시킬 수 있습니다 . " 따라서 종종 bash의 경우와 같이 따옴표를 올바르게 사용하는 것이 매우 중요합니다. 여기서 정규식 일치가 아닌 문자열 하위 일치를 확인하고 싶습니다.


3

TI 기본-32

토큰 화 된 언어를 사용한다고 생각했습니다. Ans에서 문자열로 실행하고, false이면 0을, true이면 반복되는 문자열의 길이를 반환합니다.

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 그렇게 만들기가 너무 힘들었습니다.
Josiah Winslow

좋은 생각. 문자열 조작은 가장 어려운 작업 중 하나입니다. 그러나 나는 이와 같은 몇 가지 답변을 게시 했으므로 이제 경쟁자가 있다고 생각합니다.)
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사용 여부 를 테스트 하지 않습니다. 오히려 문자열이 반복되는 문자열인지 아닌지
Optimizer

P : 난 그냥 스마트 엉덩이가 되려고 노력했다, 알
Mardoxx

2

ECMAScript 6 (34 36 )

또 다른 ES6 답변이지만 xnor의 트릭을repeat 사용 하지 않고 사용합니다 .

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

Firefox와 같은 ES6 가능 브라우저의 콘솔에서 실행해야합니다.


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의 솔루션만큼 영리하지는 않았습니다. 독창적이 되려면 ... c에서 같은 아이디어를 다시 작성했습니다.

설명:

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)

Firefox와 같은 ES6 가능 브라우저의 콘솔에서 실행해야합니다.

불필요한 반복이 많지만 왜 그것을 피하기 위해 더 길게 만드는 것입니까?

  • 편집 # 1 : 함수로 변환하여 몇 바이트를 절약했습니다. Optimizer에 감사합니다!
  • 편집 # 2 : 더 많은 바이트를 절약하기위한 스프레드 연산자 트릭을위한 hsl 덕분에!
  • 편집 # 3 : 그리고 또 다른 3 바이트 Rob W. 덕분에!

더 많은 바이트를 절약하는 함수로 변환 할 수 있습니다
Optimizer

@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

자바 8, 28 바이트

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

온라인으로 사용해보십시오.

설명:

입력 문자열이 정규식과 일치하는지 확인합니다. 여기서 전체 문자열과 일치하도록 String#matches암시 적으로 추가 ^...$됩니다.
정규 표현식 자체에 대한 설명 :

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