Грайте в ланцюжок слів


15

Коли я був молодшим, я використовував гру для слів під назвою Word word . Це було дуже просто. Перший гравець вибирає слово; наступний гравець вимовляє ще одне слово, яке починається з тієї самої літери, якою закінчилось попереднє слово. Це триває назавжди, поки хтось не здасться! Хитрість полягає в тому, що ви не можете вживати одне і те ж слово двічі (якщо тільки хто не забув, що це слово було навіть використано!). Зазвичай ми граємо з певною темою, щоб зробити її важче. Але зараз я хочу, щоб ви склали програму, щоб зробити це для мене.

Виклик

Напишіть повну програму або функцію, щоб знайти всі найдовші ланцюги слів за допомогою заданого набору слів і початкового слова.

Це , тому найкоротший код виграє!

Вхідні дані

Є два входи: список та початкове слово. Стартове слово не буде у списку. Усі вхідні регістри 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 впевнений
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
Арктур

1
@RikerW Я думаю, що також варто згадати коментар Мартіна "Перегляд коду: Зробити код трохи менш неправильним / Код Гольф: Створення коду трохи менш довгим" коментар з чату тут.
Арктур

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.
користувач81655

Ах нвм - я подумав, що поп може взяти індекс як свій перший аргумент, як у python.
гр.ч.

Це рішення недійсне для кількох вихідних послідовностей
TanMath

@TanMath Виправлено, хоча він порушує один із тестових випадків.
користувач81655


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

Я вважаю, що тут, мабуть, є набагато більше гольфу, тому я, мабуть, оновлю його.

Де-гольф

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 link - Якщо я цього не зробив правильно, просто дайте мені знати: D


ви могли б додати посилання на ideone для тестування?
TanMath

Так, я оновлю свою відповідь на це @TanMath
Danwakeem

Посилання має містити код для гольфу, а не версію, що не використовується для гольфу. Таким чином, ми можемо підтвердити версію для гольфу, яку ви подаєте на виклик.
TanMath
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.