Ordenar palabras para encajar en una cadena dada

10

Dada una cadena de letras y un conjunto de palabras, genera un orden de las palabras para que se puedan encontrar en la cadena colocando letras que no son necesarias. Las palabras pueden aparecer más de una vez en el conjunto de palabras. La cadena de entrada y todas las palabras constarán de 1 a 1000 letras minúsculas cada una. Las letras que se dejarán caer pueden aparecer dentro de palabras o entre palabras.

Su programa o función puede aceptar la cadena de letras y las palabras como listas, una cadena o desde STDIN, y debe mostrar todas las palabras en un orden correcto como una lista o salida de cadena. Si hay más de una solución correcta, solo envíe una de ellas. Si no hay una solución correcta posible, envíe una lista vacía o una cadena vacía.

Ejemplos:

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)

Este es el código de golf. El menor número de bytes gana.

Editar: explicó que los caracteres adicionales pueden estar dentro de las palabras.

Caballero Lógico
fuente
¿Puede el formato de entrada ser una cadena y luego otra lista de las cadenas restantes?
Pomo de la puerta
@Pomo de la puerta, sí, está bien. Las estructuras de entrada y salida son flexibles. Añadido al desafío.
Logic Knight el
De los casos de prueba parece que las letras caídas siempre están entre palabras. ¿Es eso así? Debería indicarlo en el desafío, o incluir un caso de prueba con letras en una palabra
Luis Mendo
No entiendo ese tercer caso de prueba; su respuesta se pone ccantes bbpero las subcadenas bby ccaparecen solo una vez y la bbsubcadena aparece primero
Neil
@Neil, en la ccbcbparte de la cadena sacamos la ccsalida bbluego de soltar el medio c.
Logic Knight el

Respuestas:

5

Pyth, 20 24 bytes

Mi primer intento en Pyth :)

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

Cómo 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: lleva mucho tiempo en el tercer ejemplo ( dababbabadbaccbcbaaacdacdbdd aa bb cc dd ba ba ba ab ac da db dc).

Monja permeable
fuente
5

Pyth, 10 bytes

h@s./Myz.p

Demostración

Este programa tiene mucha fuerza bruta. Primero construye cada subconjunto de la entrada, luego cada partición de los subconjuntos, luego verifica el primero que es un reordenamiento de la lista de palabras. No se maneja ninguna posibilidad a través de errores sin salida a stdout, lo que está permitido por meta consenso. El error se puede eliminar por 2 bytes adicionales.

Tenga en cuenta que para muchos de los casos de prueba dados, el programa no se completará en un período de tiempo razonable.

isaacg
fuente
Te perdiste el segundo caso de prueba.
Leaky Nun
@KennyLau Cuando intento ese caso, simplemente no regresa en un período de tiempo razonable. Sin embargo, no da la respuesta incorrecta. Creo que funciona ¿Tiene un caso de prueba donde devuelve una respuesta, y esa respuesta es incorrecta?
isaacg
Muy buen método.
Leaky Nun
Me has derrotado
Leaky Nun
¿Podría agregar eso a la respuesta?
Leaky 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)

Acepta una cadena y un conjunto de palabras y devuelve un conjunto de palabras o undefineden caso de error. Agregue 2 bytes si debe devolver la cadena vacía en caso de falla ( ?q:``), en cuyo caso esta versión alternativa solo tiene 120 bytes y devuelve la cadena vacía en caso de falla, e incluso puede guardar 2 bytes si se le permite devolver 0 en caso de falla:

(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:``

(Después de escribir esto, noté que el algoritmo es básicamente el mismo que la respuesta Pyth de @ KennyLau).

Edición editada: actualizada después de la aclaración de la pregunta, pero ahora es realmente lenta en el tercer caso de prueba; Lo puse en marcha la noche anterior y esta mañana me di cuenta de que realmente había encontrado la solución, entre 30 y 40 horas más tarde. Sin embargo, fui muy malo y le di la solución (funciona mejor con la solución inversa, que verificará al instante).

Neil
fuente
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 debería ser posible jugar más golf usando un enfoque diferente, pero esto lo hará por ahora.

Ungolfed y código de prueba:

Pruébalo aquí.

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

Salida:

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

Groovy (44 bytes)

No puedo creer que nadie más haya usado expresiones regulares para esto ...

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

Explicación

/${b.join('|')}/- Crear una expresión regular para encontrar cualquiera de las palabras en una cadena.
.findAll(...)- Encuentra y recoge todas las ocurrencias en la cadena en una matriz.
.join(" ")- Unir la matriz junto con espacios.

Básicamente, si no hay ocurrencias, la matriz está vacía y devuelve una cadena vacía implícitamente. Si encuentra ocurrencias, devuelve un objeto de matriz con las ocurrencias y luego lo aplana en una cadena.

Urna de pulpo mágico
fuente