가위 바위 보에서 자신을 반복하지 마십시오


26

Codegolf가 Rock-Paper-Scissors 토너먼트 를 가질 것이라는 소문에 대해, 당신은 사각없는 단어 의 주제를 조사합니다 . 문자로 이루어진 단어는 R, P, S이다 평방없는 이 두 번 반복하는 시퀀스를 포함하지 않는 경우. 즉, 단어는 다음과 같이 쓸 수 없습니다

a x x b

ab길이의 단어와 x최소 길이의 단어 하나, 모든 문자 만든이 R, P, S.

태스크

생성하는 프로그램 쓰기 평방없는 글자의 단어를 R, P, S길이의 n수는 어디에서 1 <= n <= 10입력으로한다.

예를 들어 길이가 3 인 제곱없는 단어는

RPR, RSR, RPS, RSP, SPS, SRS, SRP, SPR, PRP, PSP, PSR,PRS

길이가 4 인

RPRS, RPSR, RPSP, RSRP, RSPR, RSPS, PRPS, PRSR, PRSP, PSRP, PSRS, PSPR, SRPR, SRPS, SRSP, SPRP, SPRS,SPSR

및 참고 예를 들어, SPSP또는 PRPR평방 무료로하지 않습니다

규칙

  • 이것은 코드 골프이며, 가장 짧은 프로그램 승리이며 표준 허점은 닫힙니다.
  • 단어를 인쇄하거나 메모리에 만들 수 있습니다.
  • 프로그램이 함수로 작성되었을 수 있습니다.

참고 문헌

사각형없는 단어에 대한 Wikipedia 항목

주어진 길이의 제곱없는 3 항 단어의 수는 https://oeis.org/A006156있습니다.

관련 : 임의 길이의 3 차 Squarefree 단어


4
n>3반복되는 문자와 반복되는 시퀀스에 대해 약간의 혼동이 있었기 때문에 테스트 사례 는 좋은 생각입니다.
Laikoni

샌드 박스에서 계획된 후속 조치에 대해 의견을 말하십시오 : codegolf.meta.stackexchange.com/a/14133/45211
mschauer

6
"자연어"태그가 여기에 적용되어야한다고 생각하지 않습니다
Leo

1
아, "단어"에서 "단어"가 확장되어 제거했습니다.
mschauer

1
아니요, 여기에는 SP SP
mschauer

답변:


20

루비, 39 바이트

->n{(?P*n..?S*n).grep_v /[^RPS]|(.+)\1/}

이 비효율적 인 함수는 N P와 N S 사이에 알파벳순으로 길이가 N 인 모든 문자열을 생성 한 다음 비 RPS 문자를 포함하는 대부분의 문자열을 필터링합니다. 실제 squarefree 확인은 Regexp 역 참조를 사용합니다 (.+)\1.

N = 10에 대해 적당한 시간 내에 끝나는 더 관용적 인 65 바이트 :

->n{%w[R P S].repeated_permutation(n).map(&:join).grep_v /(.+)\1/}

편집 : G B 덕분에 바이트를 저장했습니다.


grep_v에 괄호가 필요하지 않으며 슬래시 (1 바이트 저장) 사이에 공백이 필요합니다.
GB

6
" 유감스럽게도 비효율적 "은 아마도이 사이트에 대한 꽤 많은 답변을 설명 할 것입니다.
기금 모니카의 소송

10

젤리 , 15 14 바이트

“RPS”ṗẆ;"f$$Ðḟ

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

작동 원리

“RPS”ṗẆ;"f$$Ðḟ  Main link. Argument: n

“RPS”ṗ          Cartesian power; yield all strings of length n over this alphabet.
            Ðḟ  Filterfalse; keep only strings for which the quicklink to the left 
                returns a falsy result.
           $      Monadic chain. Argument: s (string)
      Ẇ             Window; yield the array A of all substrings of s.
          $         Monadic chain. Argument: A
       ;"             Concatenate all strings in A with themselves.
         f            Filter; yield all results that belong to A as well.

7

레티 나 , 28 바이트

+%1`1
R$'¶$`P$'¶$`S
A`(.+)\1

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

단항으로 입력 받습니다.

설명

+%1`1
R$'¶$`P$'¶$`S

이것은 length 로 구성된 모든 문자열을 생성 합니다 . 이를 수행하는 방법 은 각 줄 에서 첫 번째 를 반복해서 바꾸는 것 입니다. 의이 같은 라인에 대해 생각하자 , 경기의 앞에 모든이며, 경기 후 모든 것 (그들은 것 및 각각 정규식 대체 구문, 그러나 그 모습 덜 직관적). 우리는 대체 와 곳, 줄 바꿈입니다. 따라서이 치환 전체 결과 실제로 와 라인 3 부를 인 교체 , , 각각 세 각 사본이다. 모든 프로세스가 대체 되면이 프로세스가 중지됩니다 .RPSn1<1><>$`$'1R>¶<P>¶<S<R>¶<P>¶<S>1RPS1

A`(.+)\1

마지막으로 반복이 포함 된 모든 행을 버립니다.


나는 반복적으로 교체 한 것 1(.*)으로 $1R¶$1P¶$1S하지만 바이트 수는 동일합니다.
Neil



5

자바 8, 285 277 바이트

import java.util.*;Set r=new HashSet();n->p("",((1<<3*n)+"").replaceAll(".","PRS"),n)void p(String p,String s,int n){int l=s.length(),i=0;if(l<1&&(s=p.substring(0,n)).equals(s.replaceAll("(.*)\\1","")))r.add(s);for(;i<l;p(p+s.charAt(i),s.substring(0,i)+s.substring(++i,l),n));}

Java는 거의 항상 장황하지만이 경우에는 이와 같은 과제에 적합한 언어가 아닙니다. 부분 문자열로 순열을 생성하는 것은 성능과 비효율적입니다.

그래도 확실히 더 골프를 칠 수 있습니다.

@Jakob 덕분에 -8 바이트 .

설명:

여기에서 시도하십시오. (3보다 높은 테스트 케이스에서는 성능이 너무 좋지 않지만 로컬에서는 작동합니다 ..)

import java.util.*;   // Required import for Set and HashSet

Set r=new HashSet();  // Result-Set on class-level

n->                   // Method with integer parameter and no return-type
  p("",((1<<3*n)+"").replaceAll(".","PRS"),n)
                      //  Get all permutations and save them in the Set
                      // End of method (implicit / single-line return-statement)

void p(String p,String s,int n){
                      // Separated method with 2 String & int parameters and no return-type
  int l=s.length(),   //  The length of the second input-String
      i=0;            //  Index-integer, starting at 0
  if(l<1              //  If the length is 0,
     &&(s=p.substring(0,n)).equals(s.replaceAll("(.*)\\1","")))
                      //  and it doesn't contain a repeated part:
    r.add(s);         //   Add it to the result-Set
  for(;i<l;           //  Loop (2) from 0 to `l`
    p(                //   Recursive-call with:
      p+s.charAt(i),  //    Prefix-input + the character of the second input at index `i`
      s.substring(0,i)+s.substring(++i,l),
                      //    and the second input except for this character
      n)              //    and `n`
  );                  //  End of loop (2)
}                     // End of separated method

1
이 람다는 어떻습니까 n->p("",((1<<3*n)+"").replaceAll(".","PRS"),n)? 또한, 왜 안 리팩토링 for(;i<1;p(...));while(i<l)p(...);?
Jakob

@Jakob 감사합니다. 그리고 저는 항상 for(;...;)정직하게 코드 골프 습관을 사용합니다. 최악의 경우와 같은 바이트 수 while(...)이며 바이트를 저장하기 위해 for 루프 안에 무언가를 넣을 수 있습니다. 그래서 나는 while결코 코드 카운트에 전혀 사용하지 않으려 고 노력 합니다. 그것은 그것을 늘리거나 동일하게 유지하므로 개인적으로 더 나은 가독성을 방해하지 않습니다. ;)
Kevin Cruijssen

1
예, 항상 주어진 바이트 수에서 가능한 한 골프 코드를 읽을 수 있도록하려고합니다. 아마도 헛된 추구!
Jakob

잠깐, 내 람다는 실제로 여기서 작동합니까? 나는 조금 부주의했다 ... 그것은 n PRS 시퀀스 의 문자열을 생성하는 반면 원래 루프는 2 ^ ( n -2) 시퀀스로 생성했습니다.
Jakob

@Jakob n곱하기 "PRS"가 정확합니다. 광산은 바이트를 절약하고 성능을 저하 시켰지만 코드 골프를 사용하는 사람은 더 많이 생성했기 때문에 더 많이 생성했습니다. ;)
Kevin Cruijssen '11



4

펄 5 , 37 바이트

sub r{grep!/(.+)\1/,glob"{R,S,P}"x<>}

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

함수는 사용 가능한 제곱 문자열의 배열을 반환합니다.

설명 :

glob길이와 입력이 같은 R, S 및 P의 모든 조합을 생성합니다. 이 grep문장은 정사각형이 아닌 것을 제거합니다.


괄호 확장 활용!
Dom Hastings

3

R , 97 바이트

cat((x=unique(combn(rep(c('p','r','s'),n),n<-scan(),paste,collapse='')))[!grepl("(.+)\\1",x,,T)])

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

combn(rep(c('p','r','s'),n),n,paste,collapse='')모든 계산 n과 - CHARACTER 문자열을 p, r, s하지만 불행하게도 우리가 그것을 uniquify하고 정규 표현식과 일치하는 취할 수 있도록 많은 (*), 복제 (.+)\1펄 스타일의 매칭을 사용하여, 우리는 결과 목록을 인쇄 할 수 있습니다.

(*) 기술적으로 3n문자 의 모든 조합을 한 p,r,s번에 3 번 반복 하여 생성 n한 다음 문자열을 직접 paste(..., collapse='')계산하는 대신 각 조합에 적용 3^n하지만 expand.grid(실제 카티 전 곱) 보다 골퍼 입니다.


3

자바 스크립트 (Firefox 30-57), 69 바이트

f=n=>n?[for(x of f(n-1))for(y of'RPS')if(!/(.+)\1/.test(y+=x))y]:['']

사각형이없는 단어의 모든 하위 문자열에도 사각형이 없으므로 검사를 재귀 적으로 수행 할 수 있습니다.



2

JavaScript (ES6), 93 바이트

n=>[...Array(3**n)].map(g=(d=n,i)=>d?'RPS'[i%3]+g(d-1,i/3|0):'').filter(s=>!/(.+)\1/.test(s))

RPS숫자를 사용하여 0부터 3ⁿ까지의 모든 정수를 (반전 패딩 된) 밑수 3으로 변환하고 사각형이없는 단어를 필터링합니다.


2

줄리아, 88

f(n)=[filter(A->!ismatch.(r"(.+)\1",join(A)),Iterators.product(repeated("RPS",n)...))...]

멋진 것은 없습니다.


1

C # / LINQ, 169

Enumerable.Range(0,(int)Math.Pow(3,n)).Select(i=>string.Concat(Enumerable.Range(1,n).Select(p=>"PRS"[(i/(int)Math.Pow(3,n-p))%3]))).Where(s=>!Regex.IsMatch(s,@"(.+)\1"))

이것을하는 더 좋은 방법이 있어야합니다 :)



1

k, 56 바이트

f:{$[x;(,/"RPS",/:\:f x-1){x@&~~/'(2,y)#/:x}/1_!x;,""]}

네이티브 정규 표현식이 없기 때문에 k가 한 번 곡선 뒤에 있습니다. 그것을 구현하는 문자가 더 간단한 squarefree 확인으로 저장되었으므로 재귀 솔루션을 사용했습니다.

$[ test ; if-true ; if-false ]

k의 삼항 연산자입니다. 여기서 우리는 길이가 0이 아닌 흥미로운 것들을 수행하고 길이가 0 인 단어를 요구하면 빈 문자열 하나를 반환합니다.

(,/"RPS",/:\:f x-1)

"RPS"및 모든 n-1 길이의 제곱없는 단어의 데카르트 곱을 취합니다. , / : \ : 오른쪽의 각 요소를 왼쪽으로 연결하여 길이 n 배열의 길이 3 배열을 제공합니다. , / 이것을 길이 3n 배열로 평탄화합니다.

{x@&~~/'(2,y)#/:x}

각 문자열의 첫 번째 n자를 가져와 두 번째 n과 비교 한 다음 일치하지 않는 위치로만 배열을 줄입니다. 이전 결과에 제곱이 없다는 것을 알고 있으므로 첫 번째 문자부터 시작하는 하위 문자열 만 일치하면됩니다. 여기서 확인을 단순화하면 재귀를 구현하는 데 사용 된 문자의 가치가 있습니다. 마지막으로

/1_!x

람다는 왼쪽의 초기 결과 세트에 람다를 적용하여 1에서 (워드 길이) -1까지 각 하위 문자열 길이를 반복합니다. ! x는 0에서 x-1까지의 목록을 생성 한 다음 1_은 첫 번째 요소를 제거합니다 (0 길이의 하위 문자열은 항상 일치하므로)

몇 개의 문자를 희생 시키면 .zs를 사용하여 함수 이름에 의존하지 않고 자체 참조 할 수 있으며, 길이 n-1까지 하위 문자열을 검사하는 대신 성능을 위해 floor (n / 2) 만 검사합니다. 그것은 7700k에서 약 120 초 만에 길이가 49 단어 (5207706 인)를 찾아서 4GB의 무료 32 비트 k 한계에 도달합니다.

{$[x;(,/"RPS",/:\:.z.s x-1){x@&~~/'(2,y)#/:x}/1+!_x%2;,""]}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.