Ordenação de palavras para caber em uma determinada sequência

10

Dada uma sequência de letras e um conjunto de palavras, produza uma ordem das palavras para que elas possam ser encontradas na sequência, descartando letras desnecessárias. As palavras podem ocorrer mais de uma vez no conjunto de palavras. A sequência de entrada e todas as palavras consistirão em 1 a 1000 letras minúsculas cada. As letras a serem descartadas podem ocorrer dentro das palavras ou entre as palavras.

Seu programa ou função pode aceitar a sequência de letras e as palavras como listas, uma sequência de caracteres ou de STDIN e deve gerar todas as palavras na ordem correta como saída de uma lista ou sequência de caracteres. Se houver mais de uma solução correta, envie apenas uma delas. Se não houver uma solução correta, produza uma lista vazia ou uma sequência vazia.

Exemplos:

dogcatfrog cat frog dog
-> dog cat frog

xxcatfixsxhingonxgrapexxxfishingcxat cat grape catfish fishing
-> catfish grape fishing cat

dababbabadbaccbcbaaacdacdbdd aa bb cc dd ba ba ba ab ac da db dc
-> da ab ba ba ba cc bb aa ac dc db dd

flea antelope
->
(no solution)

Isso é código de golfe. O menor número de bytes vence.

Editar: explicou que caracteres extras podem estar dentro das palavras.

Cavaleiro Lógico
fonte
O formato de entrada pode ser uma sequência e depois outra lista das sequências restantes?
Maçaneta
@ Maçaneta, sim, tudo bem. As estruturas de entrada e saída são flexíveis. Adicionado ao desafio.
Logic Knight
Nos casos de teste, parece que as letras descartadas estão sempre entre as palavras. É assim mesmo? Você deve declarar isso no desafio ou incluir um caso de teste com letras em uma palavra
Luis Mendo
Eu não entendo esse terceiro caso de teste; sua resposta é colocada ccantes, bbmas as substrings bbe ccaparecem apenas uma vez e a bbsubstring aparece primeiro.
194 Neil
@ Neil, na ccbcbparte da string que produzimos a ccsaída bbdepois de largar o meio c.
Logic Knight

Respostas:

5

Pitão, 20 24 bytes

Minha primeira tentativa em Pyth :)

Jcw;FG.ptJI:hJj".*"G0jdG

Como funciona:

Jcw;FG.ptJI:hJj".*"G0jdG
Jcw                         assign("J",chop(input()))
    FG.ptJ                  for G in permutations(tail(J)):
          I:hJj".*"G0        if match(head(J),join(".*",G)):
                     jdG      print(join(" ",G))

Notas: leva muito tempo no terceiro exemplo ( dababbabadbaccbcbaaacdacdbdd aa bb cc dd ba ba ba ab ac da db dc).

Freira Furada
fonte
5

Pitão, 10 bytes

h@s./Myz.p

Demonstração

Este programa é muito força bruta. Primeiro, ele constrói todos os subconjuntos da entrada, depois todas as partições dos subconjuntos, depois verifica o primeiro, que é uma reordenação da lista de palavras. Nenhuma possibilidade é tratada através de erros, sem saída para stdout, o que é permitido por meta consenso. O erro pode ser removido por 2 bytes extras.

Observe que, para muitos dos casos de teste fornecidos, o programa não será concluído dentro de um período de tempo razoável.

isaacg
fonte
Você perdeu o segundo caso de teste.
Leak Nun #
@KennyLau Quando tento esse caso, ele simplesmente não retorna em um período de tempo razoável. Não dá a resposta errada, no entanto. Eu acho que funciona. Você tem um caso de teste em que ele retorna uma resposta, e essa resposta está errada?
Isaacg
Método muito bom.
gotejante Nun
Você me derrotou.
gotejante Nun
Você poderia adicionar isso à resposta?
gotejante Nun
1

JavaScript (ES6), 119 bytes

(s,a,t=``,...r)=>a[0]?a.find((w,i)=>(b=[...a],b.splice(i,1),f(s,b,w+t,w,...r)))&&q:~s.search(t.split``.join`.*`)&&(q=r)

Aceita uma sequência de caracteres e uma matriz de palavras e retorna uma matriz de palavras ou undefinedcom falha. Adicione 2 bytes se precisar retornar a sequência vazia em caso de falha ( ?q:``); nesse caso, essa versão alternativa terá apenas 120 bytes e retornará a sequência vazia em caso de falha e poderá salvar 2 bytes se for permitido retornar 0 em caso de falha:

(s,a,t=``,...r)=>a[0]?a.reduce((q,w,i)=>q||(b=[...a],b.splice(i,1),f(s,b,w+t,w,...r)),0):~s.search([...t].join`.*`)?r:``

(Depois de escrever isso, notei que o algoritmo é basicamente o mesmo que a resposta Pyth de @ KennyLau.)

Edição editada: atualizada após o esclarecimento da pergunta, mas agora é muito lenta no terceiro caso de teste; Comecei na noite anterior e nesta manhã acabei de perceber que ele realmente encontrou a solução, algo entre 30 e 40 horas depois. Eu fui realmente malvado e dei a solução para ele (funciona melhor com a solução invertida, que será verificada instantaneamente).

Neil
fonte
1

Java 7, 256 bytes

import java.util.*;String c(String...a){Map s=new HashMap();int j,i=1,l=a[0].length();for(;i<a.length;i++)if((j=a[0].indexOf(a[i]))>-1)s.put(j,s.get(j)!=null?s.get(j)+" "+a[i]:a[i]);a[0]="";for(j=0;j<l;j++)a[0]+=s.get(j)!=null?s.get(j)+" ":"";return a[0];}

Definitivamente, deveria ser possível jogar mais isso usando uma abordagem diferente, mas isso funcionará por enquanto.

Ungolfed & código de teste:

Experimente aqui.

import java.util.*;
class M{
  static String c(String... a){
    Map s = new HashMap();
    int j,
        i = 1,
        l = a[0].length();
    for(; i < a.length; i++){
      if((j = a[0].indexOf(a[i])) > -1){
        s.put(j, s.get(j) != null
                  ? s.get(j) + " " + a[i]
                  : a[i]);
      }
    }
    a[0] = "";
    for(j = 0; j < l; j++){
      a[0] += s.get(j) != null
               ? s.get(j) + " "
               : "";
    }
    return a[0];
  }

  public static void main(String[] a){
    System.out.println(c("dogcatfrog", "cat", "frog", "dog"));
    System.out.println(c("xxcatfixsxhingonxgrapexxxfishingcxat", "cat", "grape", "catfish", "fishing"));
    System.out.println(
        c("dababbabadbaccbcbaaacdacdbdd ", "aa", "bb", "cc", "dd", "ba", "ba", "ba", "ab", "ac", "da", "db", "dc"));
    System.out.println(c("flea", "antelope"));
  }
}

Resultado:

dog cat frog 
cat grape fishing 
da ab ba ba ba bb db ac cc aa dd 
Kevin Cruijssen
fonte
1

Groovy (44 bytes)

Não acredito que mais ninguém usou expressões regulares para isso ...

{a,b->a.findAll(/${b.join('|')}/).join(" ")}

Explicação

/${b.join('|')}/- Crie uma regex para encontrar qualquer uma das palavras em uma sequência.
.findAll(...)- Encontre e colete todas as ocorrências na string em uma matriz.
.join(" ")- Una a matriz com espaços.

Basicamente, se não houver ocorrências, a matriz estará vazia e retornará uma sequência vazia implicitamente. Se encontrar ocorrências, ele retornará um objeto de matriz com as ocorrências e o achatará em uma sequência.

Urna de polvo mágico
fonte