อย่าพูดซ้ำตัวเองใน Rock-Paper-Scissors


26

เมื่อข่าวลือว่า Codegolf จะมีการเป่ายิ้งฉุบแข่งขันคุณมองเข้าไปในหัวข้อของคำตารางฟรี คำที่ทำจากตัวอักษรR, P, Sเป็นตารางฟรีถ้ามันไม่ได้มีลำดับที่ซ้ำสองครั้ง กล่าวคือคำนั้นไม่สามารถเขียนเป็น

a x x b

ที่aและbเป็นคำที่มีความยาวใด ๆ และxเป็นคำที่มีความยาวอย่างน้อยหนึ่งทั้งหมดที่ทำของตัวอักษรR, ,PS

งาน

จงเขียนโปรแกรมที่สร้างเป็นตารางที่ปราศจากคำพูดของตัวอักษรR, P, Sความยาวnจำนวนที่1 <= n <= 10จะนำมาเป็น input

ตัวอย่าง

ตัวอย่างเช่นคำที่ไม่มีความยาว 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ไม่เป็นรูปสี่เหลี่ยม

กฎระเบียบ

  • นี่คือ codegolf, โปรแกรมที่สั้นที่สุดชนะ, ช่องโหว่มาตรฐานถูกปิด
  • คุณสามารถพิมพ์คำหรือสร้างคำเหล่านั้นในหน่วยความจำ
  • โปรแกรมของคุณอาจถูกเขียนเป็นฟังก์ชัน

อ้างอิง

รายการ Wikipedia สำหรับคำที่ไม่มีสี่เหลี่ยม

จำนวนคำศัพท์ที่ไม่มีความยาวตามตารางที่ให้นั้นอยู่ในhttps://oeis.org/A006156

ที่เกี่ยวข้อง: Ternary Squarefree Words ที่มีความยาวตามอำเภอใจ


4
กรณีทดสอบสำหรับn>3จะเป็นความคิดที่ดีเพราะมีความสับสนเกี่ยวกับตัวละครซ้ำกับลำดับซ้ำ
Laikoni

โปรดแสดงความคิดเห็นเกี่ยวกับการติดตามการวางแผนในกล่องทราย: codegolf.meta.stackexchange.com/a/14133/45211
mschauer

6
ฉันไม่คิดว่าควรใช้แท็ก "ภาษาธรรมชาติ" ที่นี่
Leo

1
อา "ขยายคำ" ใน "ภาษาธรรมชาติ" ฉันลบมันออก
mschauer

1
ไม่มันมี SP SP แบบสี่เหลี่ยม
mschauer

คำตอบ:


20

Ruby, 39 ไบต์

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

ฟังก์ชันที่ไม่มีประสิทธิภาพอย่างสนุกสนานนี้สร้างสตริงความยาว N ทั้งหมดที่อยู่ตามลำดับตัวอักษรระหว่าง N Ps และ N Ss จากนั้นกรองส่วนใหญ่ที่มีอักขระที่ไม่ใช่ RPS ที่เช็ค squarefree จริงเพียงแค่ใช้ backreference (.+)\1Regexp:

สำนวน65 ไบต์ที่เสร็จสิ้นภายในระยะเวลาที่เหมาะสมสำหรับ N = 10:

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

นี้จะสร้างทุกสายที่สร้างขึ้นจากความยาวRPS nวิธีที่เราทำเช่นนี้คือการแทนที่อันแรก1ในแต่ละบรรทัดซ้ำ ๆ ลองคิดเกี่ยวกับเส้นเป็น<1>ที่<เป็นทุกอย่างในหน้าของการแข่งขันและ>เป็นทุกอย่างหลังจากที่การแข่งขัน (พวกเขากำลัง$`และ$'ตามลำดับใน regex เปลี่ยนตัวไวยากรณ์ แต่ดูผู้ที่ใช้งานง่ายน้อยกว่า) เราแทนที่1ด้วยR>¶<P>¶<S, ที่ไหนคือ linefeeds ดังนั้นผลเต็มรูปแบบของการทดแทนนี้เป็นจริง<R>¶<P>¶<S>ซึ่งเป็นสามชุดของเส้นกับ1เปลี่ยนR, P, Sตามลำดับในแต่ละสามเล่ม กระบวนการนี้จะหยุดเมื่อทุกอย่าง1ถูกแทนที่

A`(.+)\1

ในที่สุดเราก็ทิ้งทุกบรรทัดที่มีการทำซ้ำ


ฉันจะได้เปลี่ยนซ้ำ ๆ1(.*)ด้วย$1R¶$1P¶$1Sแต่ไบต์นับเหมือนกัน
Neil

6

Husk , 15 14 ไบต์

-1 ไบต์ขอบคุณ Zgarb!

fȯεfoE½QΠR"RPS

ลองออนไลน์!

สร้างลำดับที่เป็นไปได้ทั้งหมดของความยาวที่ถูกต้องและเก็บเฉพาะรายการที่มีสตริงย่อยทั้งหมด (ยกเว้นอันที่ว่างเปล่า) เท่านั้นที่ประกอบด้วยสองส่วนที่แตกต่างกัน

ประณามฉันต้องการเอาชนะเยลลี่ที่นี่จริงๆ


3
14 ไบต์เพื่อผูกด้วยเยลลี่
Zgarb


5

Java 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 จะพูดได้เกือบทุกครั้ง แต่ในกรณีนี้มันไม่ใช่ภาษาที่เหมาะสมสำหรับความท้าทายเช่นนี้ การสร้างการเรียงสับเปลี่ยนด้วยสตริงย่อยนั้นไม่ดีต่อประสิทธิภาพและประสิทธิภาพ

สามารถตีกอล์ฟได้มากกว่านี้

-8 ไบต์ขอบคุณที่@Jakob

คำอธิบาย:

ลองที่นี่ (ประสิทธิภาพต่ำเกินไปสำหรับกรณีทดสอบด้านบน 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)วิธีการเกี่ยวกับแลมบ์ดานี้: นอกจากนี้ทำไมไม่ refactor for(;i<1;p(...));เพื่อwhile(i<l)p(...);?
Jakob

@ Jakob ขอบคุณ และฉันมักจะใช้for(;...;)codegolfing-habbit เพื่อซื่อสัตย์ กรณีที่เลวร้ายที่สุดมันเป็นจำนวนไบต์เดียวกันกับwhile(...)กรณีที่ดีที่สุดบางอย่างสามารถอยู่ภายใน for-loop เพื่อบันทึก bytes ดังนั้นฉันจึงพยายามที่จะไม่ใช้whilecodegolfing เลยเพราะมันจะไม่เกิดประโยชน์กับจำนวนไบต์ต่อไป มันเพิ่มหรือยังคงเหมือนเดิมดังนั้นฉันเองไม่ต้องกังวลกับความสามารถในการอ่านที่ดีขึ้น ;)
Kevin Cruijssen

1
ใช่ฉันพยายามทำให้โค้ดกอล์ฟของฉันอ่านง่ายที่สุดเท่าที่จะเป็นไปได้ในจำนวนไบต์ที่กำหนด อาจเป็นการแสวงหาที่ไร้ประโยชน์!
Jakob

เดี๋ยวก่อนแลมบ์ดาของฉันทำงานที่นี่จริงหรือไม่? ฉันไม่สนใจเลย ... มันสร้างสตริงของn PRSวนวนในขณะที่ลูปดั้งเดิมของคุณสร้างขึ้นด้วยลำดับ 2 ^ ( n -2)
Jakob

@Jakob nเวลา "PRS" ถูกต้อง ฉันสร้างมากขึ้นเพราะมันบันทึกเป็นไบต์ (และลดประสิทธิภาพ แต่ใครที่ใส่ใจกับ codegolf) ;)
Kevin Cruijssen



4

Perl 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สตริงอักขระด้วยp, r, sแต่ก็น่าเสียดายที่ซ้ำกันหลายคน (*) ดังนั้นเราจึง uniquify มันและใช้เวลาเหล่านั้นที่ตรงกับ regex ไม่(.+)\1ใช้การจับคู่ Perl สไตล์แล้วเราพิมพ์ออกรายการผลลัพธ์

(*) ในทางเทคนิคมันสร้างการรวมกันทั้งหมดของ3nตัวอักษรในการp,r,sทำซ้ำ 3 ครั้งnในเวลาจากนั้นนำpaste(..., collapse='')ไปใช้กับแต่ละชุดมากกว่าการคำนวณ3^nสตริงโดยตรง แต่นี่คือ golfier กว่าexpand.grid(ผลิตภัณฑ์คาร์ทีเซียนที่แท้จริง)


3

JavaScript (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))

แปลงจำนวนเต็มทั้งหมดจาก 0 ถึง3ⁿเป็นเบส (กลับด้าน) เป็น 3 โดยใช้RPSเป็นตัวเลขและกรองพวกมันสำหรับคำที่ไม่มีสี่เหลี่ยม


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

F #, 143

let f n=[1..n]|>List.fold(fun l _->List.collect(fun s->["R";"P";"S";]|>List.map((+)s))l)[""]|>Seq.filter(fun x->not(Regex.IsMatch(x,"(.+)\1")))

เป็นคำตอบที่ดี #!
aloisdg พูดว่า Reinstate Monica

1
มันไม่ได้เป็นขนาดเล็กที่สุดของภาษา แต่เดี๋ยวก่อนข้ออ้างใด ๆ ที่จะใช้มัน :)
เจสัน Handby

1
ฉันรู้สึกว่าคุณ ภาษานี้ดีมาก
aloisdg พูดว่า Reinstate Monica

1

k, 56 ไบต์

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

การขาด regex ดั้งเดิมทำให้ k ดีหลังเส้นโค้งหนึ่งครั้ง ฉันไปกับโซลูชันแบบเรียกซ้ำเนื่องจากตัวละครที่จะนำไปใช้งานนั้นได้รับการบันทึกโดยการตรวจสอบแบบสี่เหลี่ยมจัตุรัสที่ง่ายกว่า

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

เป็นตัวดำเนินการที่ประกอบไปด้วย k ของที่นี่เราทำสิ่งที่น่าสนใจสำหรับความยาวไม่เป็นศูนย์และส่งกลับสตริงที่ว่างเปล่าเดียวถ้าถูกถามสำหรับคำที่มีความยาวเป็นศูนย์

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

ใช้ผลิตภัณฑ์คาร์ทีเซียนของ "RPS" และคำสี่เหลี่ยมจัตุรัสความยาว n-1 ทั้งหมด , /: \: รวมองค์ประกอบของด้านขวาไปทางซ้ายโดยให้อาร์เรย์ความยาว 3 อาร์เรย์มีความยาว n อาร์เรย์ , / แบนสิ่งนี้ลงในอาร์เรย์ 3n ความยาว

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

ใช้ตัวอักษร n ตัวแรกของแต่ละสตริงและเปรียบเทียบกับตัวที่สองจากนั้นลดอาร์เรย์ให้เหลือเฉพาะที่ไม่ตรงกัน เนื่องจากเรารู้ว่าผลลัพธ์ก่อนหน้านี้เป็นรูปแบบที่ไม่มีรูปสี่เหลี่ยมเฉพาะสตริงย่อยที่เริ่มต้นที่ตัวอักษรตัวแรกต้องการการจับคู่ - การทำให้การตรวจสอบที่นี่ง่ายขึ้นนั้นคุ้มค่ากับตัวอักษรที่ใช้ในการเรียกซ้ำ สุดท้าย

/1_!x

ใช้แลมบ์ดากับผลลัพธ์เริ่มต้นที่ตั้งค่าไปทางซ้ายวนซ้ำความยาวซับสตริงแต่ละช่วงจาก 1 ถึง (ความยาวคำ) -1 ! x สร้างรายการจาก 0 ถึง x-1 จากนั้น 1_ จะลบองค์ประกอบแรก (เนื่องจากสตริงย่อยความยาว 0 จะจับคู่เสมอ)

เสียสละตัวละครสองสามตัวเราสามารถใช้. zs เพื่ออ้างอิงตัวเองแทนที่จะพึ่งพาชื่อฟังก์ชั่นและแทนที่จะตรวจสอบวัสดุที่มีความยาวสูงสุด n-1 ตรวจสอบเฉพาะชั้น (n / 2) เพื่อประสิทธิภาพ พบความยาวทั้งหมด 49 คำ (ซึ่งมี 5207706) ในเวลาประมาณ 120 วินาทีใน 7700k เหนือกว่าที่ฉันพบในขีด จำกัด 4GB ของฟรี 32-bit k

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.