단어 사슬을 재생


15

어렸을 때 Word Chain 이라는 단어 게임을 합니다. 매우 간단했습니다. 첫 번째 플레이어는 단어를 선택합니다. 다음 플레이어는 이전 단어와 같은 문자로 시작하는 다른 단어를 말합니다. 누군가 포기할 때까지 이것은 영원히 계속됩니다! 속임수는 같은 단어를 두 번 사용할 수 없다는 것입니다. 일반적으로 특정 주제를 다루기 어렵게 만듭니다. 그러나 지금, 당신이 나를 위해 이것을 할 수있는 프로그램을 만들고 싶습니다.

도전

주어진 단어 세트와 시작 단어를 사용하여 가능한 가장 긴 단어 체인을 찾기위한 전체 프로그램 또는 함수를 작성하십시오.

이것은 이므로 가장 짧은 코드가 승리합니다!

입력

목록과 시작 단어의 두 가지 입력이 있습니다. 시작 단어는 목록에 없습니다. 입력은 모두 소문자 ASCII이며 목록에는 중복 단어가 포함되지 않습니다.

산출

목록에서 다음과 같은 모든 단어 순서 :

  • 시작 단어는 시퀀스에서 첫 번째 단어입니다.

  • 각 후속 단어는 이전 단어의 마지막 문자와 동일한 문자로 시작합니다.

  • 시퀀스의 길이가 가장 깁니다 .

가장 긴 시퀀스가 ​​여러 개 있으면 모두 출력합니다.

시퀀스가 반드시 모든 목록 단어를 포함 할 필요는 없습니다. 때로는 불가능합니다 (테스트 사례 참조). 다시 말하지만, 어떤 단어도 두 번 사용할 수 없습니다!

테스트 케이스

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 sure
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
코드 골프 : 몇 바이트를 절약하기 위해 기하 급수적으로 빠른 프로그램을 실행하는 기술 : P
Arcturus

1
@RikerW 나는 여기서 채팅에서 Martin의 "코드 검토 : 코드를 약간 덜 잘못 작성 / 코드 골프 : 코드를 약간 덜 길게"주석을 회상 할 가치가 있다고 생각합니다.
Arcturus

4

자바 스크립트 (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

테스트

브라우저 간 호환성을 높이기 위해 테스트에서 기본 매개 변수가 사용되지 않습니다.


splice o[r.length]?대신 및 대신 pop을 사용할 수 있다고 생각합니다 o.length>r.length?.
grc

@grc 감사합니다. o[r.length]팁이 정말 마음에 듭니다 ! 그래도 어떻게 사용할 수 있는지 모르겠습니다 pop.
user81655

Ah nvm-pop은 파이썬에서와 같이 첫 번째 인수로 색인을 사용할 수 있다고 생각했습니다.
grc

이 솔루션은 여러 출력 시퀀스에 유효하지 않습니다
TanMath

@TanMath 고정되었지만 테스트 사례 중 하나를 위반합니다.
user81655


1

펄 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

경고! 긴 목록에서이 스크립트를 사용하려면 많은 메모리가 필요합니다! 그것은 7 (6 + 여분의 1)에서 나에게 훌륭했지만 13 (12 + 1)에서는 그렇지 않았습니다.

최종 입력을 제거하고 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(" ; ");}

나는 여기서 할 수있는 골프가 훨씬 더 많을 것이라고 생각한다.

골프 골프

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


테스트를 위해 아이 데온 링크를 추가 할 수 있습니까?
TanMath

네, @TanMath
Danwakeem의

링크에는 골프화되지 않은 버전이 아닌 골프 코드가 포함되어야합니다. 그러면 도전 과제에 제출 한 골프 버전을 확인할 수 있습니다.
TanMath
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.