Tüm dizeleri çıkar


34

Bir harf kümesi göz önüne alındığında, bu harflerden yapılan tüm dizeleri çıkar. (Bu, kümenin Kleene yıldızı .) Örneğin {'a','b'}, dizgiler:

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

Giriş: Boş olmayan farklı harflerden oluşan bir koleksiyon a..z. Bunlar karakter veya tek karakterli dizeler olabilir.

Çıktı: Bu harflerdeki tüm dizeler, herhangi bir sırayla, tekrarlar olmadan. Karakter listelerini dizeler olarak kullanabilirsiniz.

Bu sonsuz bir listedir;

  • Sonsuza dek koşuyor, daha fazla karakter dizisi yazıyor. Bu dizeler herhangi bir düz ayrılmış biçimde yazılabilir, yani her dizenin nerede bittiğini söyleyebilirsiniz, ancak dizeler gruplara bölünmez.
  • Sayı nolarak giriş almak ve nherhangi bir düz ayrılmış biçimde ilk dizeleri çıkarmak
  • Her dizgeyi sırayla bir jeneratör nesnesinden elde etmek
  • Sonsuz bir nesne üretmek

Metodunuzun sonunda çıktıdaki her dizgiyi ürettiğinden emin olun, çünkü setten sonsuz sayıda dizge üretip asla dizgelere ulaşamazsınız.

Şunları değil çıkışı kendisini tarafından

  • nVerilen inci dizinin üretilmesin
  • Belirli bir dizenin kümeye ait olup olmadığına karar veren bir üyelik oracle

Yerleşiklere izin verilir, ancak seçmenlerden operasyonu kendilerine uygulayan ve çoğunlukla yerleşik olanlara cevap verenlere dikkat etmelerini istiyorum.


@Cyoce Ne demek istediğinden emin değilsin. Dizelerin ayrılması gerektiğini açıklığa kavuşturdum, böylece boş dizgiyi hiçbir şeyden anlatabilirsiniz.
xnor

Lütfen "N olarak verilen N. Dizenin üretilmesine" izin verilmediğini açıklayın.
Hesap MakinesiFeline

4
@CatsAreFluffy Bu bir yargılama çağrısıydı. Nce dizeyi üretmenin alternatiflere kıyasla çok kolay olacağını ve meydan okumayı daha az ilginç hale getireceğini düşünüyorum. Ayrıca, sorgulamak yerine sonsuz bir küme oluşturma fikrini yakaladığını düşünmedim.
xnor

“Sonsuz bir nesne üretmeyi” açıklayabilir misiniz? Bu, örneğin her dizeyi yığının üzerine (yığın dilleri için) ittirebileceğimiz ve program bitmeyeceğinden hiçbir çıktı üretilmese bile "sonsuza kadar" çalışmasına izin verebileceğimiz anlamına mı geliyor?
Luis Mendo

@DonMuesli Yığına çıkış, bu tür diller için kabul edilen bir çıkış yöntemi midir? Yığın, herhangi bir zamanda yalnızca bu dizeleri içerecek mi?
xnor

Yanıtlar:


26

Python 2, 53 56

-3 farkettikten sonra yield xbunun bir ifade olarak kullanılabileceğini söyledi.

def f(s):yield'';[(yield w+c)for w in f(s)for c in s]

One bayt kısa ama başlar 'aa'ziyade at '': S=lambda s:(c+w for f in[str,S]for w in f(s)for c in s). Ayrıca boş girdi için çalışmıyor.
orlp,

20

Haskell, 24 bayt

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

Sonsuz bir liste üretir.

*Main> f "abc"
["","a","b","c","aa","ba","ca","ab","bb","cb","ac","bc","cc","aaa","baa","caa","aba","bba","cba",…

Çok kötü (:)<$>s<*>f syanlış sıraya verirdi. Var f s="":(flip(:)<$>f s<*>s)ama daha uzun.
xnor

Evet. Ben 23 bayt bulduğunu f s=[]:(f s<**>map(:)s)dışında <**>değildir Prelude.
Anders Kaseorg

11

JavaScript (ES6), 61 bayt

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

@ Feersum'un Python jeneratörünün limanı. letGereklidir. Dizi anlama özelliğini kullanarak 2 bayttan tasarruf edin (başarısız ES7 teklifi, ancak Firefox 30-57'de çalışır):

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

nYukarıdaki jeneratör tarafından üretilen ilk elemanları döndüren 73 baytlık alternatif versiyon :

(s,n)=>Array(n).fill('').map(g=(r,i)=>i--?g(r+s[i%l],i/l|0):r,l=s.length)

JS'de jeneratör var mı? : 0000000
kedi,

10

Mathematica, 32 31 Bayt

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

Düzenle:

CatsAreFluffy bir bayttan sıyrıldı.


8

Perl, 39 37 35 bayt

(Önce eski bir sürümü anlatır. Yeni kısa program sonundadır)

İçin +3 içerir -alp

STDIN'de bir karakter kümesiyle çalıştırın, örn. perl -alp kleene.pl <<< "a b c"

kleene.pl (bu sürüm 34 + 3 bayttır):

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

İçin +2 ekleyin -F( -agiriş karakterleri arasında boşluk yoksa boşluk bırakın veya STDIN üzerindeki karakterler arasına virgül koyarsak -6 (yalnızca @a=""önce }) bırakın

Açıklama:

-alpSeçenekler etkin bir kod olun:

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

<>Perl'de görebileceğiniz gibi sadece okuma çizgisi için kullanılmaz, aynı zamanda kabuk tarzı globbing de yapabilir (aslında eski perls'te kabuk çağrılarak uygulanır).

Örneğin <{a,b}{1,2}>genişleyecek"a1","a2","b1","b2"

Öyleyse içindeki öğelere @Fsahipsek , aralarına virgül eklememiz gerekir. Enterpolasyon için varsayılan ara karakter, özel değişkende saklanan boşluktur $". Ayar Yani $"için ,dönecek "{@F}"içine {a,b}eğer @F=qw(a b)(Neználkovo dize olarak genişletmek)

Aslında böyle bir şeyle döngü yapmak isterdim glob"{@F}"x$n++, ancak ilk boş satırın üretilemediği sorununa devam ettim ve bulduğum tüm geçici çözümler kodu çok uzun zamandır yaptı.

Bu nedenle, bu kodun diğer bir önemli kısmı ise, forbir dizi üzerinde döngü yapmak için bir döngü kullanırsanız , döngü boyunca fazladan elemanlar zorlayabilirsiniz ve döngü de bu yeni öğeleri alır. Dolayısıyla, eğer döngüde örneğin elementindeyiz "ab", o <{@F}$_>zaman <{a,b}ab>liste içeriğinin ne olacağı genişleyecektir ("aab", "bab"). Bu yüzden eğer bunları bastırırsam @a, bir tane sola doğru uzatılmış teller de kullanılabilir duruma gelir

Yapmam gereken tek şey, döngüyü boş bir dize ile doldurmak. Bu $#a = 0( ,sayısal bağlamda olur 0) kullanılarak yapılır ve bu ilk ve tek elemanın ben kullandığım zamanki @agibi davranacak şekilde tanımlanmamasına neden olur.""

Gelişme iyilesme duzelme ilerleme

Aslında bu açıklama için testler yaparak, ilk boş girişi düzgün bir şekilde idare eden büyüyen bir küre kullanmanın kısa bir yolunu buldum. Farklı çalıştır perl -ap kleene0.pl <<< "a b"(böylece için 2 bayt ekleyin -ap)

kleene0.pl (bu sürüm 33 + 2 bayttır):

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

Tüm bu çözümler bellekteki çıktının gittikçe daha fazla olmasını sağlayacak ve programın bir süre sonra başarısız olmasına neden olacaktır. Perl globlarını tembel üretimi için skaler bağlamda kullanarak da kullanabilirsiniz, ancak bu programları daha uzun hale getirir ....


Lütfen neler olup bittiğini açıklayabilir misiniz <{@F}$_>? Teşekkürler!
andlrc

6

Pyth, 7

<s^LzQQ

Burada dene

Bu, girişin kartezyen ürününü her sayıyla 0..n-1onlardan hesaplar , birleştirir ve sonra yalnızca ilkini tutar n. Bu, 3-4'ten daha büyük sayılar veya dizgiler için çevrimiçi olarak zaman aşımına uğrar.

Alternatif olarak, sonsuz çıktı almak için Jakube'nin cevabına bakın .


5

Jöle, 8 6 bayt

⁷³p$Ȯ¿

Bu, bir alfabe kabul eden ve sonsuz bir dize listesi basan monadik bir bağlantıdır. Çevrimiçi deneyin!

Nasıl çalışır

⁷³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.

Alternatif sürüm, 6 bayt (rakipsiz)

R’ḃL}ị

Bu, sırasıyla bir alfabeyi ve istenen sayı dizisini sırasıyla sol ve sağ argüman olarak kabul eden çift yönlü bir bağlantıdır.

Bu sürümün rekabetsiz olduğunu düşünüyorum, çünkü bu zorluğun doldurulmasından sonra uygulanmış olan bijektif temel dönüşümünü kullanıyor. Çevrimiçi deneyin!

Nasıl çalışır

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.

4

Python 2, 89 84 83 bayt

x,n=input()
l=len(x)
for i in range(n):
 s=''
 while i:i-=1;s+=x[i%l];i/=l
 print s

Vay. Daha kısa ve yerleşik olmayanlar.
Morgan Thrapp

4

CJam, 16 10 bayt

6 byte tasarruf ettiğin için jimmy23013'e teşekkürler.

N{eam*_o}h

Giriş, karakter başına bir komut satırı argümanıdır. Çıktı, her satırdaki bir dizedir.

Çevrimiçi deneyin! (Ama hemen öldür ...)

açıklama

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

3

Pyth, 7 bayt

.V0j^zb

Kızartmaya alternatif. Bu program bir dize okur ve sonsuza kadar dizeleri yazdırmaya devam eder.

Açıklama:

.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

Alternatif olarak aşağıdakiler de işe yarayacaktır. Yine de biraz daha hack.

u
M^zH7

3

Haskell, 33 bayt

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

Sınav k "xyz"için, sonsuz liste["","x","y","z","xx","xy","xz","yx","yy","yz","zx","zy","zz","xxx",...]


3

MATL , 10 bayt

0cD`G@Z^DT

Çevrimiçi deneyin! Ancak sunucuda büyük işlem yükü oluşmasını önlemek için uzun süre çalışmasına izin vermeyin.

Program, dizeleri dinamik olarak, her biri farklı bir satırda görüntüler.

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

2

Python 3, 95

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

Neden itertools fonksiyonlarında bu kadar uzun isimler olmalı?


3
combinations_with_replacementasla buna değmez. Döngü kullanmanın daha kısa olduğundan eminim. Her zaman.
mbomb007

2

Ruby, 65 60 bayt

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

Bu kadar uzun yerleşik isimler ...


1
AFAIK Daha önce boşluğa ihtiyacınız yok ve p yerine p kullanabilirsiniz.
Fon Monica'nın Davası

@QPaysTaxes Alan bırakılamaz ve çıktısı gibi çıkacak argümanlarını pçağırırinspect[] ["a","b"] ["aa", "ab", ...
Doorknob

Cevabınızı yanlış anladım. Sonsuz bir dizi oluşturduğunu ve bastırdığını sanıyordum. Ancak, Array'de to_s'nin denetlemek için takma ad olduğundan eminim, bu yüzden koyar ve p aynı çıktıya sahiptir. ruby-doc.org/core-2.2.0/Array.html#method-i-to_s Alan WRT: Kontrol ettiniz mi? Kuşkusuz emin değilim, ama oldukça eminim.
Fon Monica'nın Davası

1

Pyke (işlem 31), 10 9 bayt

=blR.fbtp

Açıklama:

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

1

Scala, 69

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

Tembel akışlar bu tür şeyler için oldukça iyi.


1

Japt, 50 40 34 28 bayt

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

Girdi olduğunu "string", number of items. Çıktı uzunluğa göre sıralanır, ardından ters alfabe sıralaması Çevrimiçi test edin!

Nasıl çalışır

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.

100'den fazla öğe yapmak istiyorsanız bu sürüm biraz zaman alır. Daha hızlı bir sürüm istiyorsanız, bu 32 bayt olanını deneyin :

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

1

Tarçınlı Sakız, 6 bayt

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

Rekabet etmedi, çünkü Tarçın Sakızı bu mücadeleden sonra yapıldı.

Çevrimiçi deneyin (TIO çıkışı sınırlar).

açıklama

hİçinde Tarçın Gum koyar format ve üretme modu . İpin geri kalanı için dekompresyon yapar [%s]*. Daha %ssonra giriş ile değiştirilir ve regex ile eşleşen tüm olası dizeleri çıkaran bir jeneratör oluşturulur.


1

05AB1E , 9 bayt

g<∞*εÅв¦J

Çevrimiçi deneyin!

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

0

Python, 55 bayt

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

Bu, feersum'un 53 baytlık çözümünden daha uzundur , ancak basılı farklı bir yöntem göstermektedir. Liste l, yinelenirken okunan her dizenin her bir karakter sonekini ekleyerek güncellenir.

Kullanımı eşit derecede uzun map:

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

Aynı uzunluk Python 3'te yapılabilir, bir karakterini kaybedebilir print()ve girişi açarak bir tanesini kaydedebilirsiniz .

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

0

Zsh , 31 bayt

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

Çevrimiçi deneyin!

Diziyi yazdırın, ardından özyinelemeden önce değişkenleri sıkıştırın. İşlev adını dahil etmesine rağmen, bu yinelemeli sürümden bir bayt daha kısadır:

for ((;;))<<<${(F)a}&&a=($^a$^@)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.