Ordnen von Wörtern, die in eine bestimmte Zeichenfolge passen

10

Geben Sie bei einer gegebenen Buchstabenfolge und einer Reihe von Wörtern eine Reihenfolge der Wörter aus, damit sie in der Zeichenfolge gefunden werden können, indem Sie nicht benötigte Buchstaben löschen. Wörter können im Wortsatz mehrmals vorkommen. Die Eingabezeichenfolge und alle Wörter bestehen jeweils aus 1 bis 1000 Kleinbuchstaben. Die zu löschenden Buchstaben können innerhalb von Wörtern oder zwischen Wörtern vorkommen.

Ihr Programm oder Ihre Funktion kann die Buchstabenfolge und Wörter als Listen, Zeichenfolgen oder von STDIN akzeptieren und muss alle Wörter in der richtigen Reihenfolge als Listen- oder Zeichenfolgenausgabe ausgeben. Wenn es mehr als eine richtige Lösung gibt, geben Sie nur eine davon aus. Wenn es keine mögliche richtige Lösung gibt, geben Sie eine leere Liste oder eine leere Zeichenfolge aus.

Beispiele:

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)

Das ist Code Golf. Die niedrigste Anzahl von Bytes gewinnt.

Bearbeiten: Erklärt, dass zusätzliche Zeichen in Wörtern enthalten sein können.

Logikritter
quelle
Kann das Eingabeformat eine Zeichenfolge und dann eine andere Liste der verbleibenden Zeichenfolgen sein?
Türknauf
@ Doorknob, ja, das ist in Ordnung. Eingabe- und Ausgabestrukturen sind flexibel. Zur Herausforderung hinzugefügt.
Logic Knight
Aus den Testfällen geht hervor, dass die abgelegten Buchstaben immer zwischen Wörtern liegen. Ist das so? Sie sollten dies in der Herausforderung angeben oder einen Testfall mit Buchstaben in ein Wort aufnehmen
Luis Mendo
Ich verstehe diesen dritten Testfall nicht. Ihre Antwort steht ccvor, bbaber die Teilzeichenfolgen bbund werden ccnur einmal bbangezeigt, und die Teilzeichenfolge wird zuerst angezeigt.
Neil
@Neil, in dem ccbcbTeil des Strings geben wir die ccdann-Ausgabe aus, bbnachdem wir die Mitte fallen gelassen haben c.
Logic Knight

Antworten:

5

Pyth, 20 24 Bytes

Mein erster Versuch auf Pyth :)

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

Wie es funktioniert:

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

Anmerkungen: Im dritten Beispiel ( dababbabadbaccbcbaaacdacdbdd aa bb cc dd ba ba ba ab ac da db dc) dauert es lange .

Undichte Nonne
quelle
5

Pyth, 10 Bytes

h@s./Myz.p

Demonstration

Dieses Programm ist sehr brutal. Es erstellt zuerst jede Teilmenge der Eingabe, dann jede Partition der Teilmengen und sucht dann nach der ersten, bei der die Wortliste neu angeordnet wird. Es werden keine Möglichkeiten durch Fehler ohne Ausgabe an stdout behandelt, was durch Metakonsens zulässig ist. Der Fehler kann für 2 zusätzliche Bytes entfernt werden.

Beachten Sie, dass das Programm für viele der angegebenen Testfälle nicht in einem angemessenen Zeitraum abgeschlossen wird.

isaacg
quelle
Sie haben den zweiten Testfall verpasst.
Undichte Nonne
@KennyLau Wenn ich diesen Fall versuche, kehrt er einfach nicht in einem angemessenen Zeitraum zurück. Es gibt jedoch nicht die falsche Antwort. Ich denke es funktioniert. Haben Sie einen Testfall, in dem eine Antwort zurückgegeben wird und diese Antwort falsch ist?
isaacg
Wirklich schöne Methode.
Undichte Nonne
Du hast mich besiegt.
Undichte Nonne
Könnten Sie das der Antwort hinzufügen?
Undichte Nonne
1

JavaScript (ES6), 119 Byte

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

Akzeptiert eine Zeichenfolge und ein Array von Wörtern und gibt ein Array von Wörtern oder undefinedbei einem Fehler zurück. Fügen Sie 2 Bytes hinzu, wenn die leere Zeichenfolge bei einem Fehler zurückgegeben werden muss ( ?q:``). In diesem Fall beträgt diese alternative Version nur 120 Byte und gibt die leere Zeichenfolge bei einem Fehler zurück. Sie kann sogar 2 Byte speichern, wenn bei einem Fehler 0 zurückgegeben werden darf:

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

(Nachdem ich dies geschrieben hatte, bemerkte ich, dass der Algorithmus im Grunde der gleiche ist wie die Pyth-Antwort von @ KennyLau.)

Bearbeitet Bearbeiten: Nach Klärung der Frage aktualisiert, ist aber beim dritten Testfall sehr langsam. Ich habe es in der vorletzten Nacht ausgelöst und heute Morgen habe ich gerade bemerkt, dass es tatsächlich die Lösung gefunden hat, irgendwo zwischen 30 und 40 Stunden später. Ich war wirklich gemein und fütterte es mit der Lösung (es funktioniert am besten mit der umgekehrten Lösung, die sofort überprüft wird).

Neil
quelle
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];}

Es sollte definitiv möglich sein, dies mehr mit einem anderen Ansatz zu spielen, aber dies wird vorerst reichen.

Ungolfed & Testcode:

Probieren Sie es hier aus.

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

Ausgabe:

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

Groovy (44 Bytes)

Ich kann nicht glauben, dass sonst niemand Regexe dafür verwendet hat ...

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

Erläuterung

/${b.join('|')}/- Erstellen Sie einen regulären Ausdruck, um eines der Wörter in einer Zeichenfolge zu finden.
.findAll(...)- Suchen und sammeln Sie alle Vorkommen in der Zeichenfolge in einem Array.
.join(" ")- Verbinden Sie das Array mit Leerzeichen.

Wenn keine Vorkommen vorhanden sind, ist das Array grundsätzlich leer und gibt implizit eine leere Zeichenfolge zurück. Wenn es Vorkommen findet, gibt es ein Array-Objekt mit den Vorkommen zurück und glättet es dann zu einer Zeichenfolge.

Magische Krakenurne
quelle