Alle Zeichenfolgen ausgeben

34

Geben Sie alle Zeichenfolgen aus, die aus diesen Buchstaben bestehen, und geben Sie eine Reihe von Buchstaben aus. (Dies ist der Kleene-Star des Sets.) Beispielsweise {'a','b'}lauten die Zeichenfolgen wie folgt :

'', 'a', 'b', 'aa', 'ab', 'ba', 'bb', 'aaa', 'aab', ...

Eingabe: Eine nicht leere Sammlung unterschiedlicher Buchstaben a..z. Dies können Zeichen oder Einzelzeichenketten sein.

Ausgabe: Alle Zeichenfolgen in diesen Buchstaben, in beliebiger Reihenfolge, ohne Wiederholungen. Sie können Listen von Zeichen als Zeichenfolgen verwenden.

Dies ist eine unendliche Liste, sodass Sie sie folgendermaßen ausgeben können:

  • Laufen für immer und schreiben immer mehr Strings. Diese Zeichenfolgen können in jedem flach getrennten Format geschrieben werden. Dies bedeutet, dass Sie erkennen können, wo die einzelnen Zeichenfolgen enden, die Zeichenfolgen jedoch nicht in Gruppen unterteilt sind.
  • Nehmen Sie eine Zahl nals Eingabe und geben Sie die ersten nZeichenfolgen in einem beliebigen, flach getrennten Format aus
  • Jede Zeichenfolge wird nacheinander von einem Generatorobjekt ausgegeben
  • Ein unendliches Objekt erzeugen

Stellen Sie sicher, dass Ihre Methode letztendlich alle Zeichenfolgen in der Ausgabe erzeugt, da es möglich ist, unendlich viele Zeichenfolgen aus der Menge zu erzeugen, ohne auf bestimmte Zeichenfolgen zuzugreifen.

Sie können es nicht ausgeben von

  • Produziere die nangegebene Saiten
  • Bereitstellung eines Mitgliedschaftsorakels, das entscheidet, ob eine bestimmte Zeichenfolge zur Gruppe gehört

Built-ins sind erlaubt, aber ich bitte die Wähler, Antworten zu beachten, die die Operation selbst implementieren, anstatt solche, die sich meistens auf ein eingebautes System stützen.

xnor
quelle
@Cyoce Nicht sicher, was du meinst. Ich habe klargestellt, dass die Zeichenfolgen getrennt werden müssen, damit Sie die leere Zeichenfolge von nichts unterscheiden können.
26.
Bitte erläutern Sie, warum "das Erzeugen der N-ten Zeichenkette mit N" nicht erlaubt ist.
CalculatorFeline
4
@CatsAreFluffy Es war ein Urteilsspruch. Ich denke, die N-te Saite wäre im Vergleich zu den Alternativen zu einfach und würde die Herausforderung weniger interessant machen, vor allem, weil einige Sprachen eine beliebige Basiskonvertierung eingebaut haben. Außerdem habe ich nicht gedacht, dass die Idee, eine unendliche Menge zu generieren, aufgegriffen wird, anstatt sie abzufragen.
26.
Können Sie erklären, "ein unendliches Objekt zu produzieren"? Heißt das, wir können zum Beispiel jeden String auf den Stack schieben (für Stack-Sprachen) und ihn "für immer" laufen lassen, auch wenn niemals eine Ausgabe erzeugt wird, weil das Programm nicht beendet wird?
Luis Mendo
@DonMuesli Ist die Ausgabe auf den Stack eine akzeptierte Ausgabemethode für solche Sprachen? Und wird der Stapel zu irgendeinem Zeitpunkt nur diese Zeichenfolgen enthalten?
Xnor

Antworten:

26

Python 2, 53 56

-3 nach der Erkenntnis, dass yield xals Ausdruck verwendet werden kann.

def f(s):yield'';[(yield w+c)for w in f(s)for c in s]
Feersum
quelle
Ein Byte kürzer, aber beginnt bei 'aa'anstatt an '': S=lambda s:(c+w for f in[str,S]for w in f(s)for c in s). Funktioniert auch nicht für die leere Eingabe.
Orlp
20

Haskell, 24 Bytes

f s=[]:[b:a|a<-f s,b<-s]

Erzeugt eine unendliche Liste.

*Main> f "abc"
["","a","b","c","aa","ba","ca","ab","bb","cb","ac","bc","cc","aaa","baa","caa","aba","bba","cba",…
Anders Kaseorg
quelle
Schade, (:)<$>s<*>f swürde die falsche Reihenfolge geben. Es gibt f s="":(flip(:)<$>f s<*>s)aber es ist länger.
xnor
Ja. Ich hatte das 23-Byte gefunden, f s=[]:(f s<**>map(:)s)außer das <**>ist nicht drin Prelude.
Anders Kaseorg
11

JavaScript (ES6), 61 Byte

function*g(s){yield'';for(let r of g(s))for(c of s)yield c+r}

Port des Python-Generators von @ feersum. Das letist notwendig. Sparen Sie 2 Byte mithilfe eines Array-Verständnisses (fehlgeschlagener ES7-Vorschlag, funktioniert jedoch in Firefox 30-57):

function*g(s){yield'';[for(r of g(s))for(c of s)yield c+r]}

Alternative Version für 73 Bytes, die die ersten nvom obigen Generator ausgegebenen Elemente zurückgibt :

(s,n)=>Array(n).fill('').map(g=(r,i)=>i--?g(r+s[i%l],i/l|0):r,l=s.length)
Neil
quelle
JS hat Generatoren? : 0000000
Katze
10

Mathematica, 32-31 Bytes

Do[Echo/@#~Tuples~n,{n,0,∞}]&

Bearbeiten:

CatsAreFluffy hat ein Byte abgeschabt.

Murphy
quelle
8

Perl, 39 37 35 Bytes

(Beschreibt zuerst eine ältere Version. Das neue kürzere Programm ist am Ende)

Beinhaltet +3 für -alp

Führen Sie mit dem Zeichensatz auf STDIN aus, z perl -alp kleene.pl <<< "a b c"

kleene.pl (Diese Version ist 34 + 3 Bytes):

$#a=$"=","}for(@a){push@a,<{@F}$_>

Fügen Sie +2 für -F(implizites Löschen, -awenn keine Leerzeichen zwischen den Eingabezeichen vorhanden sind, oder -6 (nur @a=""vorher }) hinzu, wenn in STDIN bereits Kommas zwischen den Zeichen stehen

Erläuterung:

Die -alpOptionen machen den Code effektiv:

BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    our @F = split(' ', $_, 0);
    $#a = $" = ',';
}
foreach $_ (@a) {
    use File::Glob ();
    push @a, glob('{' . join($", @F) . '}' . $_);
}

Wie Sie <>in Perl sehen können, wird es nicht nur zum Lesen von Zeilen verwendet, sondern kann auch das Globbing im Shell-Stil ausführen (tatsächlich wurde es in alten Perls durch Aufrufen der Shell implementiert).

Zum Beispiel <{a,b}{1,2}>wird zu erweitern"a1","a2","b1","b2"

Wenn wir also die Elemente in haben, müssen @Fwir nur Kommas dazwischen hinzufügen. Das Standardzeichen für die Interpolation ist das Leerzeichen, das in einer speziellen Variablen gespeichert wird $". Wenn Sie also einstellen $", ,wird dies "{@F}"zu {a,b}if @F=qw(a b)(Globs werden als Zeichenfolgen erweitert).

Eigentlich hätte ich gerne eine Schleife mit so etwas gemacht glob"{@F}"x$n++, aber ich bin immer wieder auf das Problem gestoßen, dass die erste leere Zeile nicht generiert wird und alle Problemumgehungen, die ich fand, den Code zu lang machten.

Ein weiterer wesentlicher Teil dieses Codes ist, dass Sie, wenn Sie eine forSchleife über ein Array ausführen, während der Schleife zusätzliche Elemente darauf drücken können, und die Schleife auch diese neuen Elemente aufnimmt. Wenn wir also in der Schleife zB am Element sind "ab", dann <{@F}$_>wird erweitert, zu <{a,b}ab>welchem ​​im Listenkontext ("aab", "bab"). Wenn ich diese also @adrücke, werden auch die nach links verlängerten Saiten verfügbar

Alles was ich noch tun muss, ist die Schleife mit einer leeren Zeichenkette zu füllen. Dies geschieht mit $#a = 0( ,im numerischen Kontext wird 0), wodurch das erste und einzige Element von @aundef wird, das sich so verhält, wie ""ich es verwende

Verbesserung

Tatsächlich habe ich bei Tests für diese Erklärung einen kurzen Weg gefunden, einen wachsenden Globus zu verwenden, der den ersten leeren Eintrag richtig handhabt. Ausführen als perl -ap kleene0.pl <<< "a b"(also 2 Bytes hinzufügen für -ap)

kleene0.pl (Diese Version ist 33 + 2 Bytes):

$"=",";print<$z,>;$z.="{@F}";redo

All diese Lösungen behalten immer mehr der Ausgabe im Speicher bei, und dies führt dazu, dass das Programm nach einiger Zeit fehlschlägt. Sie können Perl-Globs auch für die verzögerte Generierung verwenden, indem Sie sie im skalaren Kontext verwenden. Dadurch werden die Programme jedoch länger.

Tonne Hospel
quelle
Können Sie bitte erklären , was um vorgeht: <{@F}$_>? Vielen Dank!
andlrc
6

Pyth, 7

<s^LzQQ

Probieren Sie es hier aus

Dies berechnet das kartesische Produkt der Eingabe mit jeder Zahl aus 0..n-1, verknüpft sie und behält dann nur die erste bei n. Bei Zahlen oder Zeichenfolgen, die viel größer als 3-4 sind, tritt eine Online-Zeitüberschreitung auf.

Um eine unendliche Ausgabe zu erhalten, sehen Sie sich alternativ Jakubes Antwort an .

FryAmTheEggman
quelle
5

Gelee, 8 6 Bytes

⁷³p$Ȯ¿

Dies ist ein monadischer Link, der ein Alphabet akzeptiert und eine unendliche Liste von Zeichenfolgen ausgibt. Probieren Sie es online!

Wie es funktioniert

⁷³p$Ȯ¿    Monadic link. Argument: A (alphabet)

⁷         Set the return value to '\n'.
     ¿    While loop.
            Condition:
    Ȯ         Print the current return value and return it (always truthy).
            Body:
   $          Combine the two links to the left into a single, monadic link.
 ³              Yield A.
  p             Perform the Cartesian product of A and the current return value,
                updating the return value in the process.

Alternative Version, 6 Bytes (nicht konkurrierend)

R’ḃL}ị

Dies ist eine dyadische Verknüpfung, die ein Alphabet und die gewünschte Anzahl von Zeichenfolgen als linkes bzw. rechtes Argument akzeptiert.

Ich halte diese Version für nicht konkurrierend, da sie eine bijektive Basiskonvertierung verwendet, die implementiert wurde, nachdem diese Herausforderung in einer Sandbox ausgeführt wurde. Probieren Sie es online!

Wie es funktioniert

R’ḃL}ị    Dyadic link. Arguments: n (integer), A (alphabet)

R         Range; yield [1, ..., n].
 ’        Decrement; yield [0, ..., n-1].
   L}     Yield l, the length of A.
  ḃ       Convert every i in [0, ..., n-1] to bijective base l.
     ị    For each array of digits, retrieve the corresponding characters of A.
Dennis
quelle
4

Python 2, 89 84 83 Bytes

x,n=input()
l=len(x)
for i in range(n):
 s=''
 while i:i-=1;s+=x[i%l];i/=l
 print s
Dennis
quelle
Wow. Kürzere und ohne eingebaute.
Morgan Thrapp
4

CJam, 16 10 Bytes

Danke an jimmy23013 für das Speichern von 6 Bytes.

N{eam*_o}h

Die Eingabe besteht aus einem Befehlszeilenargument pro Zeichen. Ausgabe ist eine Zeichenfolge in jeder Zeile.

Probieren Sie es online! (Aber töte es sofort ...)

Erläuterung

N      e# Push [\n]. At each step this array will contain all strings of length N,
       e# each followed by a linefeed.
{      e# Infinite loop...
  ea   e#   Read command-line arguments.
  m*   e#   Cartesian product: pairs each letter with each string in the list.
  _o   e#   Output all the strings of the current length.
}h
Martin Ender
quelle
3

Pyth, 7 Bytes

.V0j^zb

Alternative zu @fry. Dieses Programm liest eine Zeichenfolge und druckt die Zeichenfolgen bis unendlich.

Erläuterung:

.V0      for b in (0 to infinity):
    ^zb     compute all strings of length b consisting of the input alphabet
   j        print each one on a separate line

Alternativ funktioniert auch Folgendes. Ein bisschen hackiger.

u
M^zH7
Jakube
quelle
3

Haskell, 33 Bytes

k u=do s<-[0..];mapM(\_->u)[1..s]

Zum Beispiel k "xyz"ist die unendliche Liste["","x","y","z","xx","xy","xz","yx","yy","yz","zx","zy","zz","xxx",...]

Lynn
quelle
3

MATL , 10 Bytes

0cD`G@Z^DT

Probieren Sie es online! Lassen Sie es jedoch nicht lange laufen, um eine hohe Rechenlast auf dem Server zu vermeiden.

Das Programm zeigt die Zeichenfolgen dynamisch an, wobei sich jede Zeichenfolge in einer anderen Zeile befindet.

0cD             % force display of a newline to represent the empty string
   `      T     % infinite do-while loop
    G           % push input, or nothing if no input has been taken yet
     @          % push iteration. Gives 1, 2,... in each iteration
      Z^        % Cartesian power. In the first iteration takes input implicitly 
       D        % display
Luis Mendo
quelle
2

Python 3, 95

from itertools import*
def f(x,l=0):
 while 1:print(*combinations_with_replacement(x*l,l));l+=1

Warum müssen itertools-Funktionen so lange Namen haben?

Morgan Thrapp
quelle
3
combinations_with_replacementist es nie wert. Ich bin mir ziemlich sicher, dass es kürzer ist, Loops zu verwenden. Immer.
mbomb007
2

Ruby, 65-60 Bytes

->a{n=-1;loop{puts a.repeated_permutation(n+=1).map &:join}}

So lange eingebaute Namen ...

Türknauf
quelle
1
AFAIK Sie brauchen kein Leerzeichen vor & und können p anstelle von puts verwenden.
Nic Hartley
@QPaysTaxes Das Leerzeichen kann nicht gelöscht werden und pruft inspectseine Argumente auf, die eine Ausgabe wie[] ["a","b"] ["aa", "ab", ...
Doorknob
Ich habe deine Antwort falsch verstanden. Ich dachte, es würde ein unendliches Array erzeugen und es ausdrucken. Ich bin mir jedoch ziemlich sicher, dass bei Array to_s für die Inspektion einen Alias ​​hat, sodass puts- und p-Werte dieselbe Ausgabe haben. ruby-doc.org/core-2.2.0/Array.html#method-i-to_s WRT the space: Haben Sie nachgesehen ? Ich bin mir zwar nicht sicher, aber ziemlich sicher.
Nic Hartley
1

Pyke (Festschreiben 31), 10 9 Bytes

=blR.fbtp

Erläuterung:

=b         -    set characters for base conversion to eval_or_not(input())
  l        -   len(^)
   R      -  [^, eval_or_not(input()]
    .f    - first_n(^)
      b   -    conv_base(^)
       t  -   ^[-1]
        p -  print(^)
Blau
quelle
1

Scala, 69

def f[A](s:Set[A]):Stream[List[A]]=Nil#::f(s).flatMap(x=>s.map(_::x))

Lazy Streams sind für so etwas ganz nett.

Joe K
quelle
1

Japt, 50 40 34 28 Bytes

V²o ®s1+Ul)£UgXnH)¯X¦0}Ãâ ¯V

Eingabe ist "string", number of items. Die Ausgabe wird nach Länge sortiert und anschließend in umgekehrter alphabetischer Reihenfolge. Testen Sie es online!

Wie es funktioniert

V²  o ®   s1+Ul)£  UgXnH)¯  X¦ 0}Ã â ¯  V
Vp2 o mZ{Zs1+Ul)mX{UgXnH)s0,X!=0}} â s0,V

Vp2 o      // Create the range [0..V²).
mZ{     }  // Map each item Z in this range to:
Zs1+Ul)    //  Take the base-(1+U.length) representation of Z.
mX{     }  //  Map each char X in this to:
XnH        //   Parse X as a base-32 number.
Ug   )     //   Take the char at index -^ in U.
s0,X!=0    //   If X is 0, slice it to an empty string.
â          // Uniquify the result.
s0,V       // Slice to the first V items.

Diese Version dauert eine Weile, wenn Sie mehr als 100 Elemente ausführen möchten. Wenn Sie eine schnellere Version wünschen, probieren Sie diese 32-Byte- Version aus :

V*2 o ms1+Ul)f@!Xf'0î£UgXnH}ïV
ETHproductions
quelle
1

Zimtgummi, 6 Bytes

0000000: 6801 301c e74b                           h.0..K

Nicht konkurrierend, da Zimtgummi nach dieser Herausforderung hergestellt wurde.

Probieren Sie es online aus (TIO begrenzt die Ausgabe).

Erläuterung

Das hversetzt Cinnamon Gum in den Format- und Erzeugungsmodus . Der Rest der Zeichenfolge wird auf dekomprimiert [%s]*. Das %swird dann durch die Eingabe ersetzt, und es wird ein Generator erstellt, der alle möglichen Zeichenfolgen ausgibt, die mit dem regulären Ausdruck übereinstimmen.

ein Spaghetto
quelle
1

05AB1E , 9 Bytes

g<∞*εÅв¦J

Probieren Sie es online!

g             # length of the input
 <            # - 1
  ∞           # infinite list [1, 2, 3, …]
   *          # multiply each by the length-1
    ε         # for each:
     Åв       #  custom base conversion, using the input as the list of digits
       ¦      #  chop off the first digit
        J     #  join the rest to a string
Grimmig
quelle
0

Python, 55 Bytes

s=input();l=['']
for x in l:print x;l+=[x+c for c in s]

Dies ist länger als die 53-Byte-Lösung von feersum , zeigt jedoch eine andere Methode für die Druckausgabe. Die Liste lwird aktualisiert, während sie durchlaufen wird, indem jedes Ein-Zeichen-Suffix jeder gelesenen Zeichenfolge angehängt wird.

Es ist ebenso lang zu benutzen map:

s=input();l=['']
for x in l:print x;l+=map(x.__add__,s) 

Dieselbe Länge kann in Python 3 durchgeführt werden, print()indem ein Zeichen für verloren geht und ein Zeichen durch Entpacken der Eingabe gespeichert wird.

s,*l=input(),''
for x in l:print(x);l+=[x+c for c in s]
xnor
quelle
0

Zsh , 31 Bytes

f(){<<<${(F)a};a=($^a$^@);f $@}

Probieren Sie es online!

Drucken Sie das Array aus und komprimieren Sie die Argumente, bevor Sie sie wiederholen. Trotz der Angabe des Funktionsnamens ist dies ein Byte kürzer als die iterative Version:

for ((;;))<<<${(F)a}&&a=($^a$^@)
GammaFunktion
quelle