Đừng lặp lại chính mình trong Rock-Paper-Kéo


26

Khi có tin đồn rằng Codegolf sẽ có một giải đấu Rock-Paper-Kéo, bạn nhìn vào chủ đề của những từ không vuông . Một từ được làm bằng các chữ cái R, P, Svuông miễn phí nếu nó không chứa một chuỗi mà lặp đi lặp lại hai lần. Điều đó có nghĩa là, từ này không thể được viết là

a x x b

nơi ablà những lời của bất kỳ chiều dài và xlà một từ có độ dài ít nhất một, tất cả làm bằng các chữ cái R, P, S.

Bài tập

Viết một chương trình mà tạo ra các hình vuông miễn lời của các chữ cái R, P, Schiều dài ncó số 1 <= n <= 10được thực hiện như là đầu vào.

Thí dụ

Ví dụ: các từ không có ô vuông có độ dài 3 là

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

và những người có chiều dài 4 là

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

và lưu ý rằng ví dụ SPSPhoặc PRPRkhông vuông

Quy tắc

  • Đây là codegolf, chiến thắng chương trình ngắn nhất, sơ hở tiêu chuẩn được đóng lại.
  • Bạn có thể in các từ hoặc tạo chúng trong bộ nhớ.
  • Chương trình của bạn có thể được viết như một chức năng.

Tài liệu tham khảo

Mục nhập Wikipedia trên các từ không vuông

Số lượng từ ternary không vuông có độ dài nhất định có trong https://oeis.org/A006156

Liên quan: Từ tùy ý vuông chiều dài tùy ý


4
Một trường hợp thử nghiệm n>3sẽ là một ý tưởng tốt, bởi vì đã có một số nhầm lẫn về các ký tự lặp lại so với các chuỗi lặp lại.
Laikoni

Vui lòng nhận xét về kế hoạch theo dõi trong hộp cát: codegolf.meta.stackexchange.com/a/14133/45211
mschauer

6
Tôi không nghĩ thẻ "ngôn ngữ tự nhiên" nên áp dụng ở đây
Leo

1
À, "từ" được mở rộng bằng "ngôn ngữ tự nhiên", tôi đã xóa nó.
mschauer

1
Không, nó chứa SP SP vuông
mschauer

Câu trả lời:


20

Ruby, 39 byte

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

Hàm không hiệu quả vui nhộn này tạo ra tất cả các chuỗi có độ dài N nằm theo thứ tự abc giữa N Ps và N Ss, sau đó lọc ra phần lớn có chứa các ký tự không phải RPS. Kiểm tra không gian vuông thực tế chỉ sử dụng phản hồi Regrec : (.+)\1.

65 byte thành ngữ hoàn thành trong một khoảng thời gian hợp lý cho N = 10:

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

Chỉnh sửa: Đã lưu một byte nhờ G B.


Bạn không cần dấu ngoặc đơn trên grep_v, chỉ cần một khoảng trắng giữa nó và dấu gạch chéo (lưu 1 byte)
GB

6
" vui nhộn không hiệu quả " có thể mô tả khá nhiều câu trả lời trên trang web này.
Vụ kiện của Quỹ Monica

10

Thạch , 15 14 byte

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

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

Làm thế nào nó hoạt động

“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

Võng mạc , 28 byte

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

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

Đưa đầu vào trong unary .

Giải trình

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

Điều này tạo ra tất cả các chuỗi được tạo thành RPStừ chiều dài n. Cách chúng tôi làm điều này là chúng tôi liên tục thay thế đầu tiên 1trong mỗi dòng. Chúng ta hãy nghĩ về dòng như <1>, <mọi thứ ở đâu trước trận đấu và >là tất cả mọi thứ sau trận đấu (chúng $`$'theo cú pháp thay thế regex, nhưng chúng trông kém trực quan hơn). Chúng tôi thay thế 1bằng R>¶<P>¶<S, nguồn cấp dữ liệu ở đâu . Vì vậy, toàn bộ kết quả của sự thay thế này là thực sự <R>¶<P>¶<S>, đó là ba bản sao của dòng, với sự 1thay thế với R, P, S, tương ứng, trong mỗi trong ba bản. Quá trình này dừng lại khi tất cả 1đã thay thế.

A`(.+)\1

Cuối cùng, chúng tôi chỉ cần loại bỏ tất cả các dòng có chứa một sự lặp lại.


Tôi đã nhiều lần thay thế 1(.*)bằng $1R¶$1P¶$1Snhưng số byte là như nhau.
Neil

6

Husk , 15 14 byte

-1 byte nhờ Zgarb!

fȯεfoE½QΠR"RPS

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

Xây dựng tất cả các chuỗi có thể có độ dài chính xác và chỉ giữ lại các chuỗi có tất cả các chuỗi con (trừ chuỗi trống) được tạo bởi hai nửa khác nhau.

Chết tiệt, tôi thực sự muốn đánh bại Jelly ở đây.


3
14 byte để liên kết với Jelly.
Zgarb


5

Java 8, 285 277 byte

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

Mặc dù Java hầu như luôn dài dòng, nhưng trong trường hợp này, nó chắc chắn không phải là ngôn ngữ phù hợp cho một thách thức như thế này. Tạo hoán vị với các chuỗi con là xấu cho hiệu suất và không hiệu quả.

Chắc chắn có thể được chơi golf nhiều hơn, mặc dù.

-8 byte nhờ @Jakob .

Giải trình:

Hãy thử nó ở đây. (Hiệu suất quá tệ đối với các trường hợp thử nghiệm trên 3, nhưng nó hoạt động cục bộ ..)

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
Làm thế nào về lambda này : n->p("",((1<<3*n)+"").replaceAll(".","PRS"),n). Ngoài ra, tại sao không cấu trúc lại for(;i<1;p(...));để while(i<l)p(...);?
Jakob

@Jakob Cảm ơn. Và tôi luôn luôn sử dụng for(;...;)codegolfing-hợi để thành thật. Trường hợp xấu nhất đó là cùng một số byte như while(...), trường hợp tốt nhất có thể được đặt bên trong vòng lặp for để lưu byte. Vì vậy, tôi cố gắng hoàn toàn không sử dụng whiletrong codegolfing, vì dù sao nó cũng không bao giờ có lợi cho việc đếm byte. Nó làm tăng nó hoặc giữ nguyên, vì vậy cá nhân tôi không bận tâm với khả năng đọc tốt hơn. ;)
Kevin Cruijssen

1
Vâng, tôi luôn cố gắng làm cho mã golf của mình dễ đọc nhất có thể với số byte đã cho. Có lẽ là một sự theo đuổi vô ích!
Jakob

Đợi đã, lambda của tôi thực sự làm việc ở đây? Tôi đã hơi bất cẩn ... Nó tạo ra một chuỗi n PRS chuỗi, trong khi vòng lặp ban đầu của bạn tạo ra một chuỗi có 2 ^ ( n -2).
Jakob

@Jakob nlần "PRS" là chính xác. Của tôi đã tạo ra nhiều hơn bởi vì nó đã tiết kiệm byte (và giảm hiệu suất, nhưng ai quan tâm đến điều đó với codegolf). ;)
Kevin Cruijssen



4

Perl 5 , 37 byte

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

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

Hàm trả về một mảng của các chuỗi tự do vuông.

Giải thích:

Việc globtạo tất cả các kết hợp của R, S, & P với chiều dài bằng với đầu vào. Câu greplệnh lọc ra những cái không vuông miễn phí.


Sử dụng tuyệt vời của mở rộng cú đúp!
Dom Hastings

3

R , 97 byte

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

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

combn(rep(c('p','r','s'),n),n,paste,collapse='')tính tất cả các nchuỗi ký tự là với p, r, s, nhưng nó không may trùng lặp nhiều (*), vì vậy chúng tôi uniquify nó, và đưa những người phù hợp với regex(.+)\1 , sử dụng kết hợp perl-style, sau đó chúng tôi in ra danh sách kết quả.

(*) về mặt kỹ thuật, nó tạo ra tất cả các kết hợp các 3nchữ cái được p,r,slặp đi lặp lại 3 lần được thực hiện ncùng một lúc, sau đó áp dụng paste(..., collapse='')cho từng kết hợp thay vì tính toán 3^ntrực tiếp các chuỗi, nhưng điều này mạnh hơn một expand.grid(sản phẩm đúng của Cartesian).


3

JavaScript (Firefox 30-57), 69 byte

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

Vì tất cả các từ của từ không có ô vuông cũng không có ô vuông nên việc kiểm tra có thể được thực hiện theo cách đệ quy.



2

JavaScript (ES6), 93 byte

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

Chuyển đổi tất cả các số nguyên từ 0 thành 3ⁿ thành (đệm đảo ngược) cơ sở 3 bằng cách sử dụng RPSdưới dạng chữ số và lọc chúng cho các từ không vuông.


2

Julia, 88

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

Không có gì lạ mắt.


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"))

Phải có một cách tốt hơn để làm điều này :)



1

k, 56 byte

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

Việc thiếu regex bản địa đặt k phía sau đường cong một lần. Tôi đã đi với một giải pháp đệ quy, vì các ký tự để thực hiện nó đã được lưu bằng một kiểm tra vuông góc đơn giản hơn.

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

là toán tử tạm thời của k, ở đây chúng tôi thực hiện các công cụ thú vị với độ dài khác không và trả về một chuỗi trống duy nhất nếu được yêu cầu các từ có độ dài bằng không.

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

lấy sản phẩm cartesian của "RPS" và tất cả các từ vuông không có độ dài n-1. , /: \: nối từng phần tử bên phải sang trái, tạo ra một mảng dài 3 mảng n chiều dài. , / san phẳng nó thành một mảng dài 3n.

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

lấy n chữ cái đầu tiên của mỗi chuỗi và so sánh nó với n thứ hai, sau đó giảm mảng xuống chỉ ở nơi chúng không khớp. Bởi vì chúng ta biết kết quả trước đó là không có hình vuông, chỉ các chuỗi con bắt đầu ở ký tự đầu tiên cần khớp - đơn giản hóa việc kiểm tra ở đây là xứng đáng với các ký tự được thực hiện đệ quy. Cuối cùng,

/1_!x

áp dụng lambda cho kết quả ban đầu được đặt ở bên trái của nó, lặp lại qua mỗi độ dài chuỗi con từ 1 đến (độ dài từ) -1. ! x tạo danh sách từ 0 đến x-1, sau đó 1_ xóa phần tử đầu tiên (vì các chuỗi con có độ dài 0 sẽ luôn khớp)

Hy sinh một vài ký tự, chúng ta có thể sử dụng .zs để tự tham chiếu thay vì dựa vào tên hàm và thay vì kiểm tra các chuỗi con có chiều dài n-1 chỉ kiểm tra sàn (n / 2) để thực hiện. Nó tìm thấy tất cả 49 từ (trong đó có 5207706) trong khoảng 120 giây trên 7700k, trên đó tôi chạy vào giới hạn 4GB của k 32 bit miễn phí.

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

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.