単語チェーンを再生する


15

私が若かったとき、私はWord chainと呼ばれる単語ゲームをプレイするために使用します。とても簡単でした。最初のプレイヤーが単語を選択します。次のプレイヤーは、前の単語が終わったのと同じ文字で始まる別の単語を言います。これは誰かがgivesめるまで永遠に続きます!トリックは、同じ単語を2回使用することはできないということです(誰もがその単語を使用することさえ忘れていない限り!)。通常、私たちは特定のトピックをより難しくするために遊びます。しかし、今、私はあなたに私のためにこれをするプログラムを作って欲しいです。

チャレンジ

完全なプログラムまたは関数を作成して、指定された一連の単語と開始単語を使用して、可能な限り長い単語チェーンをすべて検索します。

これはなので、最短のコードが優先されます!

入力

入力には、リストと開始語の2つがあります。開始語はリストに含まれません。入力はすべて小文字のASCIIであり、リストには重複する単語は含まれません。

出力

次のようなリストの単語のすべてのシーケンス:

  • 開始ワードは、シーケンスの最初のワードです。

  • 後続の各単語は、前の単語の最後の文字と同じ文字で始まります。

  • シーケンスの長さは可能な限り最長です。

最長のシーケンスが複数ある場合は、それらすべてを出力します。

シーケンスには、必ずしもすべてのリストワードを含める必要はありません。それが不可能な場合もあります(テストケースを参照)。繰り返しますが、単語を2回使用することはできません!

テストケース

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
コードゴルフ:数バイトを節約するために、指数関数的な時間で高速プログラムを実行する技術:P
Arcturus

1
@RikerW Martinの「コードレビュー:コードを少し間違えにくくする/コードゴルフ:コードを少し短くする」というコメントもここで思い出す価値があると思います。
アークトゥルス

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

テスト

ブラウザー間の互換性を高めるためにテストで使用されないデフォルトのパラメーター。


スプライスのo[r.length]?代わりに、またはの代わりにポップを使用できると思いますo.length>r.length?
-grc

@grcありがとう、o[r.length]ヒントが本当に好きです!popしかし、私はどのように使用できるのかわかりません。
user81655

Ah nvm-pythonのように、popは最初の引数としてインデックスを取ることができると思った
-grc

このソリューションは、複数の出力シーケンスには無効です
-TanMath

@TanMathは修正されましたが、テストケースの1つに違反します。
user81655


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

警告!このスクリプトを長いリストで使用するには、大量のメモリが必要です!7(6プラス1)ではうまくいきましたが、13(12 + 1)ではうまくいきませんでした。

最後の入力を削除し、arrayrefの配列を生成します。arrayrefはすべての順列であり、最初の単語を最初に追加します。次に、このような各置換を、必要な連鎖プロパティを持つ配列の量をキーとするハッシュの値である別のarrayrefにプッシュします。次に、そのようなキーの最大値を見つけて、すべての配列を出力します。


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


テスト用にideoneリンクを追加できますか?
-TanMath

ええ、私はそれで私の答えを更新します@TanMath
Danwakeem

リンクには、ゴルフのないコードではなく、ゴルフのコードを含める必要があります。これにより、チャレンジ作品に提出するゴルフバージョンを確認できます。
-TanMath
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.