Ich habe diese Frage kürzlich beim Stackoverflow gesehen. Es ist eine großartige Frage, aber es gibt ein schwerwiegendes Problem mit der Frage. Sie fragen nach dem besten Weg, dies zu tun. ZB am einfachsten zu lesen, am idiomatischsten, am saubersten usw. Wissen sie nicht, dass es nicht darauf ankommt? Sie sollten sich fragen, wie Sie das mit den wenigsten Bytes Code machen sollen!
Da ich bezweifle, dass diese Frage beim Stackoverflow beantwortet wird, habe ich mich entschlossen, sie hier zu stellen.
Die Herausforderung
Sie müssen das kürzestmögliche Programm oder die kürzestmögliche Funktion schreiben, die alle möglichen Möglichkeiten zur Verschachtelung von zwei beliebigen Zeichenfolgen generiert. Wenn zum Beispiel die beiden Zeichenfolgen 'ab'
und sind 'cd'
, lautet die Ausgabe:
['abcd', 'acbd', 'acdb', 'cabd', 'cadb', 'cdab']
Wie Sie sehen, a
ist immer vor b
und c
ist immer vor d
.
IO kann in jedem vernünftigen Format vorliegen. Verwenden Sie diesen Python-Code, um Ihre Ausgabe zu überprüfen. (Kredit: JeD )
def shuffle(s,t):
if s=="":
return [t]
elif t=="":
return [s]
else:
leftShuffle=[s[0]+val for val in shuffle(s[1:],t)]
rightShuffle=[t[0]+val for val in shuffle(s,t[1:])]
leftShuffle.extend(rightShuffle)
return leftShuffle
Beispiel IO:
shuffle("$", "1234"):
['$1234', '1$234', '12$34', '123$4', '1234$']
shuffle("az", "by"):
['azby', 'abzy', 'abyz', 'bazy', 'bayz', 'byaz']
shuffle("code", "golf"):
['codegolf', 'codgeolf', 'codgoelf', 'codgolef', 'codgolfe', 'cogdeolf', 'cogdoelf',
'cogdolef', 'cogdolfe', 'cogodelf', 'cogodlef', 'cogodlfe', 'cogoldef', 'cogoldfe',
'cogolfde', 'cgodeolf', 'cgodoelf', 'cgodolef', 'cgodolfe', 'cgoodelf', 'cgoodlef',
'cgoodlfe', 'cgooldef', 'cgooldfe', 'cgoolfde', 'cgoodelf', 'cgoodlef', 'cgoodlfe',
'cgooldef', 'cgooldfe', 'cgoolfde', 'cgolodef', 'cgolodfe', 'cgolofde', 'cgolfode',
'gcodeolf', 'gcodoelf', 'gcodolef', 'gcodolfe', 'gcoodelf', 'gcoodlef', 'gcoodlfe',
'gcooldef', 'gcooldfe', 'gcoolfde', 'gcoodelf', 'gcoodlef', 'gcoodlfe', 'gcooldef',
'gcooldfe', 'gcoolfde', 'gcolodef', 'gcolodfe', 'gcolofde', 'gcolfode', 'gocodelf',
'gocodlef', 'gocodlfe', 'gocoldef', 'gocoldfe', 'gocolfde', 'goclodef', 'goclodfe',
'goclofde', 'goclfode', 'golcodef', 'golcodfe', 'golcofde', 'golcfode', 'golfcode']
Wie üblich gelten Standardlücken, und die kürzeste Antwort in Bytes gewinnt. Da es sich ursprünglich um Python handelte, würde ich gerne die kürzeste Python-Antwort sehen. (Und nein, Python ist nicht Python). Antworten in jeder Sprache sind jedoch erwünscht.
quelle
Antworten:
Pyth, 26
Probieren Sie es hier aus
Dies ist eine sehr grundlegende Implementierung der angegebenen rekursiven Formel. Es definiert eine Funktion
g
, die die erforderliche Aufgabe ausführt. Der Link ist ein modifiziertes Programm, das die Zeichenfolgen getrennt von STDIN-Zeilenumbrüchen liest, um dies zu vereinfachen. Um die Funktion aufzurufen, gehen Sie wie folgt vorg<string1><string2>
.Erweiterung:
Die beiden rekursiven Aufrufe sind sich sehr ähnlich, aber ich habe keinen Weg mehr gefunden, sie zu golfen.
quelle
Haskell,
5348 BytesDefiniert eine Funktion,
%
für diea%b
mit Zeichenfolgena,b
eine Liste von Zeichenfolgen erstellt wird.Bei zwei gegebenen Zeichenfolgen wählen wir eine der beiden Zeichen aus, aus denen das erste Zeichen entnommen werden soll. Wir werden dann auf den Rest von zwei Zeichenketten zurückgreifen und jedem Ergebnis dieses Zeichen voranstellen.
Wenn einer der Strings leer ist, ist das einzig mögliche Ergebnis der andere String.
""%""=[""]
würde auch genügen, ist aber länger.53 Bytes:
Definiert eine Funktion,
%
für diea%d
mit Zeichenfolgena,d
eine Liste von Zeichenfolgen erstellt wird.Die Funktion ist rekursiv definiert. Wenn wir ein Zeichen aus der ersten Zeichenfolge nehmen, muss es vor jedem Ergebnis des rekursiven Aufrufs auf den verbleibenden Teil der ersten Zeichenfolge mit der zweiten Zeichenfolge eingefügt werden. Symmetrisch für die andere Saite.
Wenn im Basisfall eine der Zeichenfolgen leer ist, ist das Ergebnis eine Einzelelementliste ihrer Verkettung. Dies ist kürzer als zwei Fälle für jede leere Zeichenfolge.
quelle
""%""=[""]
.Haskell, 47
%
ist der Betreiber, der diese Herausforderung löst.#
ist ein Operator, der zwei Listen aufnimmt und alle Möglichkeiten findet, sie so zu verschachteln, dass das erste Zeichen aus der ersten Zeichenfolge stammt (mit einem Kantenfall - wenn die erste Liste leer ist, ist das Ergebnis eine leere Liste), indem er rekursiv zu%
.Dann
%
funktioniert es, indem Sie es einfach#
zweimal anwenden .Bearbeiten: Die vorherige Version hatte einen Fehler, der
""%""
zurückkehrte["",""]
, also habe ich ihn behoben. Es wurde behoben, indem ein Basisfall hinzugefügt wurde%
, aus dem dann ein Basisfall mit der gleichen Länge entfernt werden konnte#
(was eigentlich keinen Sinn ergab).quelle
(#) :: [a]->[a]->[[a]]
, soa::[a]
und das Ergebnis der Typ sein sollte[[a]]
Python 2, 71 Bytes
Beispiellauf:
Mit zwei gegebenen Zeichenfolgen können
x,y
wir das erste Zeichen von nehmenx
und es jedem Ergebnis des rekursiven Aufrufs voranstellen, wobei es fehltf(x[1:],y)
. Oder wir können dasselbe mitx
undy
geschaltet machen. Indem wirx,y
entweder den Eingangp
oder dessen Umkehrung `p [:: - 1] nehmen, erhalten wir beide Möglichkeiten.Um zu vermeiden, dass ein leerer String entnommen wird
x
, schließen wir logischerweise mitx and
. Wenn beide Strings leer sind, kann keiner der Strings leer seinx
und wir erhalten eine leere Liste von Möglichkeiten, die wir mitor
dem richtigen Basisfall beheben['']
.Eine ähnliche generative Strategie in Python 3 (73 Byte):
quelle
Python, 80
Hier ist, wie gewünscht, eine Python-Antwort:
Dank Sp3000 für das Essen von 4 Bytes :)
quelle
CJam, 38
Probieren Sie es online aus
Dynamische Programmierung (mit gespeicherter Rekursion).
Erläuterung:
quelle
CJam, 32 Bytes
Teste es hier.
Das fühlt sich wirklich golfen an, aber bisher habe ich nur 4 alternative Lösungen gefunden, die alle die gleiche Byteanzahl haben:
Die Grundidee besteht darin, alle Permutationen von
0
s und1
s zu generieren , die der Zeichenfolge entsprechen, aus der die einzelnen Zeichen im Ergebnis entnommen werden sollen. Das ist alles bis einschließlich dere!
. Der Rest zieht dann einfach die Zeichen in dieser Reihenfolge aus den beiden Zeichenfolgen heraus.quelle
e*
und.*
die jedes Element um einen unterschiedlichen Betrag wiederholt. ;) (Dh ein Operator zu tun:a.*:~
. Ich nehme an, dasse*
könnte dafür verwendet werden, da es derzeit Fehler gibt, wenn zwei Listen gegeben werden.)JavaScript (Firefox 30-57),
888481 BytesBearbeiten: 4 Bytes durch Verbesserung meiner Abbruchbedingung gespeichert. 3 Bytes gespart dank @ edc65.
quelle
f=(a,b,z=(v,w)=>v[1]?f(v.slice(1),w).map(x=>v[0]+x):[v+w])=>z(a,b).concat(z(b,a))
v
als Bedingung zu verwenden, aber es kam mir nie in den Sinn, es zu verwendenv[1]
.Brachylog , 8 Bytes
Probieren Sie es online!
Nimmt die Eingabe als Liste von zwei Zeichenfolgen durch die Eingabevariable und generiert alle möglichen Verschachtelungen durch die Ausgabevariable. Da die Testfälle doppelte Verschachtelungen zuzulassen scheinen, wenn es gemeinsame Buchstaben gibt, habe ich nicht darauf geachtet, sie zu vermeiden, aber dies erzeugt viel mehr Duplikate und das nicht nur mit gemeinsamen Buchstaben. (Wenn dies nicht zulässig ist, die Duplikate für gemeinsam genutzte Buchstaben jedoch nicht erforderlich sind, fügen Sie einfach drei Bytes hinzu, um sie
{}ᵘ
als Liste ohne Duplikate auszugeben.)Im Wesentlichen generiert dies jede Partition beider Zeichenfolgen und verschachtelt sie dann in der normalen deterministischen Weise in einer beliebigen Reihenfolge. Die zusätzlichen doppelten Verschachtelungen sind auf Partitionspaare zurückzuführen, bei denen der Unterschied zwischen der Länge der ersten und der Länge der zweiten einen anderen Wert als 0 oder 1 hat, sodass einer von ihnen Abschnitte aufweist, die am Ende miteinander verkettet werden. So erzeugen Sie eine Ausgabe mit den gleichen Multiplizitäten wie die Beispielausgabe:
Brachylog , 17 Bytes
Probieren Sie es online!
Der zusätzliche Code
{lᵐ-ℕ<2&}
schlägt bei jedem Partitionspaar fehl, bei dem keine zusätzlichen Divisionen vorgenommen werden. (Ich habe die Kopfzeile in TIO geändert, um sie mit Anführungszeichen zu drucken, damit die Ausgabe in der Python-Shell einfacher überprüft werden kann.)quelle
MATL ,
3430 BytesDies basiert auf einer Idee aus dieser Antwort : Wenn die Länge der Zeichenfolgen
m
und istn
, zähle allem+n
Bitmuster mitm
gesetzten Bits auf. Eine Möglichkeit, diese Aufzählung durchzuführen, besteht darin, alle Permutationen eines Vektors mitm
Einsen undn
Nullen zu generieren und dann Duplikate zu entfernen.Probieren Sie es online!
Erläuterung
quelle
Ruby, 83 Bytes
Eine rekursive Funktion, die zurückgibt,
[a+b]
wenn eine dieser Zeichenfolgen leer ist. Andernfalls wird eine Liste von Zeichenfolgen zurückgegeben,a[0] + every string in v[a[1..-1],b]
die zu einer Liste von Zeichenfolgen hinzugefügt wurdenb[0] + every string in v[a,b[1..-1]]
quelle
Batch,
154152 Bytesquelle