เล่นห่วงโซ่คำ


15

เมื่อผมเป็นเด็กผมใช้ในการเล่นเกมคำศัพท์ที่เรียกว่าห่วงโซ่ของ Word มันง่ายมาก ผู้เล่นคนแรกเลือกคำ; ผู้เล่นคนถัดไปพูดคำอื่นที่เริ่มต้นด้วยตัวอักษรเดียวกันกับคำก่อนหน้านี้ที่ลงท้ายด้วย สิ่งนี้ดำเนินต่อไปเรื่อย ๆ จนกระทั่งมีใครยอมแพ้! เคล็ดลับคือคุณไม่สามารถใช้คำเดียวกันสองครั้ง (เว้นแต่ทุกคนลืมคำนั้นแม้ใช้!) เรามักจะเล่นกับหัวข้อที่กำหนดเพื่อให้ยากขึ้น แต่ตอนนี้ฉันต้องการให้คุณสร้างโปรแกรมเพื่อทำสิ่งนี้ให้ฉัน

ท้าทาย

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

นี่คือดังนั้นรหัสที่สั้นที่สุดชนะ!

อินพุต

มีสองอินพุต: รายการและคำเริ่มต้น คำเริ่มต้นจะไม่อยู่ในรายการ อินพุตเป็น ASCII ตัวพิมพ์เล็กทั้งหมดและรายการจะไม่มีคำที่ซ้ำกัน

เอาท์พุต

ลำดับของคำทั้งหมดจากรายการเช่นนั้น:

  • คำเริ่มต้นเป็นคำแรกในลำดับ

  • คำที่ตามมาแต่ละคำเริ่มต้นด้วยตัวอักษรเดียวกันกับตัวอักษรตัวสุดท้ายของคำก่อนหน้า

  • ความยาวของลำดับเป็นไปได้ที่ยาวที่สุด

หากมีลำดับที่ยาวที่สุดหลายชุดให้ส่งออกทั้งหมด

ลำดับไม่จำเป็นต้องมีทุกคำในรายการ บางครั้งก็เป็นไปไม่ได้ (ดูตัวอย่าง) อีกครั้งไม่สามารถใช้คำสองครั้ง!

Testcases

In: [hello, turtle, eat, cat, people] artistic
Out:  [artistic, cat, turtle, eat]
In: [lemonade, meatball, egg, grape] ham 
Out: [ham, meatball, lemonade, egg, grape]
In: [cat, cute, ewok] attic
Out: [attic, cute, ewok]
In:[cat, cute, ewok, kilo, to, otter] attic
Out: [attic, cute, ewok, kilo, otter]
In:[cat, today, yoda, attic] ferret
Out: [ferret, today, yoda, attic, cat]
In: [cancel, loitering, gnocchi, improv, vivic, child, despair, rat, tragic, chimney, rex, xylophone] attic
Out: [[attic, child, despair, rat, tragic, cancel, loitering, gnocchi, improv, vivic, chimney], [attic, cancel, loitering, gnocchi, improv, vivic, child, despair, ra', tragic, chimney]]
In: [cat, today, yoda, artistic, cute, ewok, kilo, to, otter] attic
Out: [attic, cat, today, yoda, artistic, cute, ewok, kilo, otter]

4
@downvoters คุณโปรดอธิบายได้ว่าฉันจะปรับปรุงคำถามของฉันได้อย่างไร
TanMath

@ user81655 แน่ใจ
TanMath

2
คุณสามารถเพิ่มกรณีทดสอบที่มีลำดับเอาต์พุตหลายชุดได้หรือไม่?
isaacg

@isaacg แน่นอน! ทำงานกับมัน
TanMath

@isaacg เพิ่มแล้ว! (เติมเต็มได้ไม่เกิน 15 ตัวอักษร ... )
TanMath

คำตอบ:


8

Pyth, 25 23 ไบต์

.MlZfqhMtTeMPT+Lzs.pMyQ

ชุดทดสอบ

วิธีการแก้ปัญหากำลังดุร้าย ช้าเกินไปสำหรับกรณีทดสอบขนาดใหญ่บางกรณี

ป้อนข้อมูลในแบบฟอร์ม:

attic
["cat", "today", "yoda", "to", "otter"] 

เอาท์พุทในรูปแบบ:

[['attic', 'cat', 'today', 'yoda'], ['attic', 'cat', 'to', 'otter']]

คำอธิบาย:

.MlZfqhMtTeMPT+Lzs.pMyQ
                           Q = eval(input()) (The list of words)
                           z = input()       (The starting word)
                     yQ    All subsets of the input.
                  .pM      All permutations of the subsets.
                 s         Flatten.
              +Lz          Add the starting word to the front of each list.
                           This is all possible sequences.
    f                      Filter on
     q                     The equality of
      hMtT                 The first character of each word but the first
          eMPT             The last character of each word but the last
.MlZ                       Take only the lists of maximal length.

2
คุณสามารถเพิ่มคำอธิบายได้ไหม?
TanMath

รหัสของคุณจะทำงานตลอดไปสำหรับตัวอย่างลำดับเอาต์พุตหลายตัว
TanMath

3
@ TanMath ไม่ได้เป็นเพียงแค่เลขชี้กำลังดังนั้นมันจึงช้ามาก
isaacg

5
Code golf: ศิลปะของการสร้างโปรแกรมที่รวดเร็วเป็นอย่างอื่นทำงานในเวลาแบบเอ็กซ์โพเนนเชียลเพื่อประหยัดเวลาเพียงไม่กี่ไบต์: P
Arcturus

1
@RikerW ฉันคิดว่ามันก็คุ้มค่าที่จะระลึกถึง "การทบทวนรหัส: การทำโค้ดให้ผิดน้อยลง / การตีกอล์ฟ: การสร้างรหัสยาวน้อยลง" ความคิดเห็นจากการแชทที่นี่
Arcturus

4

JavaScript (ES6), 164 ไบต์

f=(l,s,r=[[]])=>l.map((w,i)=>w[0]==s.slice(-1)&&(x=l.slice(),x.splice(i,1),o=f(x,w),a=o[0].length,b=r[0].length,r=a>b?o:a<b?r:r.concat(o)))&&r.map(q=>[s].concat(q))

คำอธิบาย

ฟังก์ชั่นวนซ้ำที่ตรวจสอบว่ารายการเอาท์พุทจะนานแค่ไหนสำหรับตัวเลือกที่เป็นไปได้ทั้งหมด

ส่งกลับอาร์เรย์ของคำอาร์เรย์

f=(l,s,r=[[]])=>            // l = list, s = starting word, r is not passed (it is
                            //     here so that it is not defined globally)
  l.map((w,i)=>             // for each word w at index i
    w[0]==s.slice(-1)&&(    // if the first letter is the same as the last letter:
      x=l.slice(),          // x = clone of the list of words
      x.splice(i,1),        // remove the current word
      o=f(x,w),             // get the list of words starting from the current word
      a=o[0].length,
      b=r[0].length,
      r=a>b?o:              // if o is longer, set r to o
        a<b?r:              // if o is shorter, keep r
        r.concat(o)         // if o is same, add it to r
    )
  )
  &&r.map(q=>[s].concat(q)) // return a list of longest lists with the starting word

ทดสอบ

พารามิเตอร์เริ่มต้นไม่ได้ใช้ในการทดสอบเพื่อให้ใช้งานร่วมกับเบราว์เซอร์ได้มากขึ้น


ฉันคิดว่าคุณสามารถใช้ pop แทนการประกบกันและแทนo[r.length]? o.length>r.length?
grc

@grc ขอบคุณฉันชอบo[r.length]เคล็ดลับจริงๆ! ฉันไม่รู้ว่าจะใช้popอย่างไร
user81655

อืม nmm - ฉันคิดว่าป๊อปอาจใช้ดัชนีเป็นอาร์กิวเมนต์แรกเช่นเดียวกับในไพ ธ อน
grc

วิธีการแก้ปัญหานี้ไม่ถูกต้องสำหรับลำดับเอาท์พุทหลาย
TanMath

@TanMath แก้ไขแม้ว่ามันจะแบ่งหนึ่งในกรณีทดสอบ
user81655

3

Python, 104

def f(d,w):
 a=[[w]]
 while a:b=a;a=[x+[y]for x in a for y in set(d)-set(x)if x[-1][-1]==y[0]]
 return b

ฉันคิดว่ามันควรจะทำงานตอนนี้ ...

ลองมันออนไลน์


1

Perl 5, 275 ไบต์

อาจจะไม่ได้เล่นกอล์ฟมากเท่าที่จะเป็นไปได้ แต่เดี๋ยวก่อนมันไม่ได้ชนะใช่ไหม?

use List::Util max;use List::MoreUtils uniq,before;use Algorithm::Permute permute;$i=pop;permute{push@c,[@ARGV]}@ARGV;for$c(@c){unshift@$c,$i;push @{$d{before{(substr$c->[$_],-1)ne(substr$c->[1+$_],0,1)}keys$c}},$c}for$m(max keys%d){say for uniq map{"@$_[0..$m+1]"}@{$d{$m}}}

ใช้มัน:

$ perl -M5.010 chain.pl cat tin cot arc
arc cat tin
arc cot tin

คำเตือน! การใช้สคริปต์นี้ในรายการยาว ๆ ต้องใช้หน่วยความจำมากมาย! มันใช้งานได้ดีสำหรับฉันในเจ็ด (หกบวกหนึ่งพิเศษ) แต่ไม่ได้อยู่ในสิบสาม (สิบสองบวกหนึ่ง)

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


0

C, 373 ไบต์

g(char*y){printf("%s, ",y);}z(char*w){int i,k=-1,v=0,j=sizeof(c)/sizeof(c[0]);int m[j],b=0;for(i=0;i<j;i++){m[v++]=c[i][0]==w[strlen(w)-1]?2:1;if(u[i]==6)m[v-1]=1;if(strcmp(w,c[i]))k=i;}printf("%s",w);for(i=0;i<j;i++){if(m[i]!=1){if(v+i!=j){g(s);for(;b<j;b++){if(u[b]==6)g(c[b]);}}else printf(", ");u[i]=6;z(c[i]);u[i]=1;}else v+=-1;}if(k!=-1)u[k]=1;if(v==0)printf(" ; ");}

ฉันเชื่อว่าอาจจะมีการตีกอล์ฟมากขึ้นฉันสามารถทำได้ที่นี่ดังนั้นฉันอาจจะอัพเดท

De กอล์ฟ

char *c[9]={"cat","today","yoda","artistic","cute","ewok","kilo","to","otter"};
u[9]={-1};
char *s="attic";

g(char*y){printf("%s, ",y);}
z(char*w){
   int i,k=-1,v=0,j=sizeof(c)/sizeof(c[0]);
   int m[j],b=0;
   for(i=0;i<j;i++){
      m[v++]=c[i][0]==w[strlen(w)-1]?i:-1;
      if(u[i]==6)m[v-1]=-1;
      if(strcmp(w,c[i]))k=i;
   }
   printf("%s",w);
   for(i=0;i<j;i++){
      if(m[i]!=-1){
         if(v+i!=j){
            g(s);
            for(;b<j;b++){
                if(u[b]==6)g(c[b]);
             }
         }else printf(", ");
         u[i]=6;
         z(c[i]);
         u[i]=-1;
      } else v+=-1;
   }
   if(k!=-1)u[k]=-1;
   if(v==0)printf(" ; ");
}

main(){
   z(s);
   printf("\n");
   return 0;
}

ลิงก์ Ideone - หากฉันทำไม่ถูกต้องแจ้งให้ฉันทราบ: D


คุณสามารถเพิ่มลิงค์ideoneสำหรับการทดสอบได้หรือไม่
TanMath

ใช่ฉันจะอัปเดตคำตอบของฉันด้วย @TanMath
Danwakeem

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