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.