Gioca alla catena di parole


15

Quando ero più giovane, gioco con un gioco di parole chiamato Catena di parole . È stato molto semplice Il primo giocatore sceglie una parola; il giocatore successivo dice un'altra parola che inizia con la stessa lettera con cui è terminata la parola precedente. Questo continua all'infinito finché qualcuno non si arrende! Il trucco è che non puoi usare la stessa parola due volte (a meno che tutti non dimenticassero che quella parola è stata usata!). Di solito giochiamo con un determinato argomento per renderlo più difficile. Ma ora, voglio che tu faccia un programma per farlo per me.

Sfida

Scrivi un programma o una funzione completi per trovare tutte le catene di parole più lunghe possibili usando un determinato set di parole e inizia la parola.

Questo è , quindi vince il codice più corto!

Ingresso

Ci sono due input: un elenco e una parola iniziale. La parola iniziale non sarà nell'elenco. Gli input sono tutti in caratteri ASCII minuscoli e l'elenco non conterrà parole duplicate.

Produzione

Tutte le sequenze di parole dell'elenco in modo tale che:

  • La parola iniziale è la prima parola della sequenza.

  • Ogni parola successiva inizia con la stessa lettera dell'ultima lettera della parola precedente.

  • La lunghezza della sequenza è la più lunga possibile .

Se sono presenti più sequenze più lunghe, emetterle tutte.

La sequenza non deve necessariamente contenere tutte le parole dell'elenco. A volte ciò non è possibile (vedi testcase). Ancora una volta, nessuna parola può essere usata due volte!

Casi test

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
@downvoter puoi spiegarmi come posso migliorare la mia domanda?
TanMath,

@ user81655 sicuro
TanMath

2
È possibile aggiungere un caso di test con più sequenze di output?
Isaacg,

@isaacg Certo! ci
sto

Aggiunto @isaacg! (Limite di 15 caratteri rispettato ...)
TanMath

Risposte:


8

Pyth, 25 23 byte

.MlZfqhMtTeMPT+Lzs.pMyQ

Suite di test

Una soluzione di forza bruta. Troppo lento per alcuni dei casi di test più grandi.

Inserisci nel modulo:

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

Output nel modulo:

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

Spiegazione:

.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
Puoi aggiungere una spiegazione?
TanMath,

Il codice viene eseguito per sempre per l'esempio della sequenza di output multipli
TanMath

3
@TanMath no è solo tempo esponenziale, quindi è molto lento.
Isaacg,

5
Code golf: l'arte di eseguire un programma altrimenti veloce in tempo esponenziale solo per risparmiare qualche byte: P
Arcturus

1
@RikerW Penso che valga anche la pena ricordare il commento di Martin "Revisione del codice: rendere il codice leggermente meno sbagliato / Code Golf: Rendere il codice leggermente meno lungo" dalla chat qui.
Arturo

4

JavaScript (ES6), 164 byte

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

Spiegazione

Una funzione ricorsiva che controlla per quanto tempo rimarrà l'elenco di output per tutte le possibili scelte.

Restituisce una matrice di matrici di parole.

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

Test

Parametro predefinito non utilizzato nel test per renderlo più compatibile con più browser.


Penso che potresti usare pop invece di splice e o[r.length]?invece di o.length>r.length?.
GRC

@grc Grazie, mi piace molto il o[r.length]consiglio! Non so come potrei usare popperò.
user81655

Ah nvm - Pensavo che il pop potesse prendere un indice come primo argomento come in Python.
GRC

Questa soluzione non è valida per più sequenze di output
TanMath

@TanMath Risolto, anche se si rompe uno dei casi di test.
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

Penso che dovrebbe funzionare ora ...

Provalo online .


1

Perl 5, 275 byte

Probabilmente non ha giocato a golf tanto quanto può essere, ma, ehi, non è comunque vincente, giusto?

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

Usalo così:

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

Avvertimento! L'uso di questo script in una lunga lista richiede molta memoria! Per me ha funzionato alla grande su sette (sei più quello extra) ma non su tredici (dodici più uno).

Rimuove l'input finale, genera una matrice di arrayrefs, dove gli arrayrefs sono tutte le permutazioni e aggiunge nuovamente la parola iniziale all'inizio. Quindi spinge ciascuna di tali permutazioni su un altro arrayref che è il valore di un hash con chiave la quantità dell'array che ha la proprietà di concatenamento desiderata. Quindi trova il massimo di tale chiave e stampa tutte le matrici.


0

C, 373 byte

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

Credo che probabilmente ci sia molto più golf che potrei fare qui, quindi probabilmente lo aggiornerò.

De-golf

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

Link Ideone - Se non l'ho fatto bene fammelo sapere: D


potresti aggiungere un link ideone per i test?
TanMath,

Sì, aggiornerò la mia risposta con esso @TanMath
Danwakeem

Il link dovrebbe contenere il codice golf, non la versione non golf. In questo modo, possiamo confermare la versione golfata che si sta presentando per la sfida funziona.
TanMath,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.