Xuất tất cả các chuỗi


34

Cho một tập hợp các chữ cái, xuất ra tất cả các chuỗi được tạo từ các chữ cái đó. (Đây là ngôi sao Kleene của tập hợp.) Ví dụ: for {'a','b'}, các chuỗi là:

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

Đầu vào: Một bộ sưu tập các chữ cái riêng biệt a..z. Đây có thể là các ký tự hoặc chuỗi ký tự đơn.

Đầu ra: Tất cả các chuỗi trong các chữ cái đó, theo bất kỳ thứ tự nào, không lặp lại. Bạn có thể sử dụng danh sách các ký tự như chuỗi.

Đây là một danh sách vô hạn, vì vậy bạn có thể xuất nó bằng cách:

  • Chạy mãi viết ngày càng nhiều chuỗi. Các chuỗi này có thể được viết bằng bất kỳ định dạng phân tách phẳng nào, có nghĩa là chúng có thể cho biết mỗi chuỗi kết thúc ở đâu, nhưng các chuỗi không được chia thành các nhóm.
  • Lấy một số nlàm đầu vào và xuất các nchuỗi đầu tiên ở bất kỳ định dạng phân tách phẳng nào
  • Mang lại lần lượt từng chuỗi từ một đối tượng trình tạo
  • Sản xuất một vật thể vô hạn

Hãy chắc chắn rằng phương thức của bạn cuối cùng tạo ra mọi chuỗi trong đầu ra, vì có thể tạo ra vô số chuỗi từ tập hợp trong khi không bao giờ nhận được một số chuỗi.

Bạn không thể xuất nó bằng

  • Sản xuất nchuỗi thứ đã chon
  • Cung cấp một orory thành viên quyết định nếu một chuỗi nhất định thuộc về tập hợp

Tích hợp được cho phép, nhưng tôi yêu cầu cử tri chú ý đến các câu trả lời tự thực hiện thao tác trên các câu hỏi chủ yếu dựa vào tích hợp.


@Cyoce Không chắc ý bạn là gì. Tôi đã làm rõ rằng các chuỗi phải được tách ra, vì vậy bạn có thể nói chuỗi trống từ không có gì.
xnor

Vui lòng giải thích tại sao "sản xuất chuỗi N cho N" không được phép.
Máy

4
@CatsAreFluffy Đó là một cuộc gọi phán xét. Tôi nghĩ rằng việc tạo chuỗi Nth sẽ quá dễ dàng so với các lựa chọn thay thế và làm cho thách thức trở nên ít thú vị hơn, đặc biệt là vì một số ngôn ngữ có tích hợp chuyển đổi cơ sở tùy ý. Ngoài ra, tôi không nghĩ rằng nó nắm bắt được ý tưởng tạo ra một tập hợp vô hạn thay vì truy vấn nó.
xnor

Bạn có thể giải thích "sản xuất một vật thể vô hạn" không? Điều đó có nghĩa là chúng ta có thể ví dụ đẩy từng chuỗi lên ngăn xếp (đối với ngôn ngữ ngăn xếp) và để nó chạy "mãi mãi", ngay cả khi không có đầu ra nào được tạo ra vì chương trình sẽ không kết thúc?
Luis Mendo

@DonMuesli Đầu ra cho ngăn xếp có phải là một phương thức đầu ra được chấp nhận cho các ngôn ngữ đó không? Và, ngăn xếp sẽ chỉ chứa các chuỗi này tại bất kỳ thời điểm nào?
xnor

Câu trả lời:


26

Con trăn 2, 53 56

-3 sau khi nhận ra rằng yield xcó thể được sử dụng như một biểu thức.

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

Một byte ngắn hơn, nhưng bắt đầu tại 'aa'chứ không phải tại '': S=lambda s:(c+w for f in[str,S]for w in f(s)for c in s). Cũng không làm việc cho đầu vào trống.
orlp

20

Haskell, 24 byte

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

Tạo ra một danh sách vô hạn.

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

Quá xấu (:)<$>s<*>f ssẽ đưa ra thứ tự sai. Có f s="":(flip(:)<$>f s<*>s)nhưng nó dài hơn.
xnor

Vâng. Tôi đã tìm thấy 23 byte f s=[]:(f s<**>map(:)s)ngoại trừ <**>không có trong đó 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}

Trình tạo Python của @ frageum. Điều letcần thiết. Lưu 2 byte bằng cách sử dụng một mảng hiểu (đề xuất ES7 không thành công, nhưng hoạt động trong Firefox 30-57):

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

Phiên bản thay thế cho 73 byte trả về các nphần tử đầu tiên được tạo bởi trình tạo ở trên:

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

JS có máy phát điện không? : 0000000
mèo

10

Toán học, 32 31 byte

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

Chỉnh sửa:

CatsAreFluffy đã loại bỏ một byte.


8

Perl, 39 37 35 byte

(Đầu tiên mô tả một phiên bản cũ hơn. Chương trình ngắn hơn mới ở cuối)

Bao gồm +3 cho -alp

Chạy với bộ ký tự trên STDIN, vd perl -alp kleene.pl <<< "a b c"

kleene.pl (phiên bản này là 34 + 3 byte):

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

Thêm +2 cho -F(thả ẩn -anếu không có khoảng trắng giữa các ký tự đầu vào hoặc -6 (chỉ@a="" trước đó }) nếu chúng tôi đã đặt dấu phẩy giữa các ký tự trên STDIN

Giải trình:

Các -alptùy chọn làm cho mã hiệu quả:

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

Bạn có thể thấy <> trong perl không chỉ được sử dụng cho readline, mà còn có thể thực hiện toàn cầu kiểu vỏ (thực tế trong các perls cổ đại, nó đã được thực hiện bằng cách gọi shell).

Ví dụ <{a,b}{1,2}> sẽ mở rộng sang"a1","a2","b1","b2"

Vì vậy, nếu chúng ta có các phần tử trong @Fchúng ta chỉ cần thêm dấu phẩy vào giữa. Mặc định giữa các ký tự cho phép nội suy là khoảng trắng, được lưu trữ trong biến đặc biệt $". Vì vậy, việc thiết $"để ,sẽ biến "{@F}"thành {a,b}nếu@F=qw(a b) (các chuỗi mở rộng dưới dạng chuỗi)

Trong thực tế, tôi thực sự muốn lặp lại với một cái gì đó như glob"{@F}"x$n++ , nhưng tôi tiếp tục gặp phải vấn đề là dòng trống đầu tiên không được tạo và tất cả các cách giải quyết mà tôi tìm thấy đã tạo ra mã quá dài.

Vì vậy, một phần thiết yếu khác của mã này là nếu bạn sử dụng một forvòng lặp trên một mảng, bạn thực sự có thể đẩy các phần tử bổ sung trên nó trong vòng lặp và vòng lặp cũng sẽ nhận các phần tử mới này. Vì vậy, nếu trong vòng lặp, chúng ta ví dụ như ở phần tử "ab", thì nó <{@F}$_>sẽ mở rộng đến <{a,b}ab>trong bối cảnh danh sách trở thành ("aab", "bab"). Vì vậy, nếu tôi đẩy chúng lên @athì các chuỗi mở rộng sang bên trái cũng trở nên khả dụng

Tất cả những gì tôi vẫn cần làm là hoàn thành vòng lặp với một chuỗi rỗng. Điều đó được thực hiện bằng cách sử dụng $#a = 0( ,trong bối cảnh số trở thành 0), điều này khiến cho phần tử đầu tiên và duy nhất @atrở thành undef sẽ hoạt động như thế nào"" khi tôi sử dụng nó

Cải thiện

Trong thực tế bằng cách thực hiện các bài kiểm tra cho lời giải thích này, tôi đã tìm thấy một cách ngắn để sử dụng một quả cầu đang phát triển xử lý đúng mục nhập trống đầu tiên. Chạy dưới dạng perl -ap kleene0.pl <<< "a b"(vì vậy thêm 2 byte cho -ap)

kleene0.pl (phiên bản này là 33 + 2 byte):

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

Tất cả các giải pháp này sẽ giữ ngày càng nhiều đầu ra trong bộ nhớ và điều đó sẽ khiến chương trình bị lỗi sau một thời gian. Bạn cũng có thể sử dụng perl globs cho thế hệ lười biếng bằng cách sử dụng chúng trong ngữ cảnh vô hướng, nhưng điều đó làm cho các chương trình dài hơn ....


Bạn có thể vui lòng giải thích những gì đang xảy ra xung quanh : <{@F}$_>? Cảm ơn!
andlrc

6

Bình 7, 7

<s^LzQQ

Hãy thử nó ở đây

Điều này sẽ tính toán sản phẩm cartesian của đầu vào với mỗi số từ 0..n-1, nối chúng và sau đó chỉ giữ đầu tiênn . Điều này sẽ hết thời gian trực tuyến cho các số hoặc chuỗi lớn hơn nhiều so với 3-4.

Ngoài ra, để có được đầu ra vô hạn, hãy nhìn vào câu trả lời của Jakube .


5

Thạch, 8 6 byte

⁷³p$Ȯ¿

Đây là một liên kết đơn âm chấp nhận một bảng chữ cái và in một danh sách các chuỗi vô hạn. Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Phiên bản thay thế, 6 byte (không cạnh tranh)

R’ḃL}ị

Đây là một liên kết dyadic chấp nhận một bảng chữ cái và số chuỗi mong muốn tương ứng là các đối số trái và phải.

Tôi coi phiên bản này không cạnh tranh, vì nó sử dụng chuyển đổi cơ sở phỏng đoán, đã được thực hiện sau khi thử thách này được đưa vào hộp cát. Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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 byte

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

Ồ Ngắn hơn và không có nội dung.
Morgan Thrapp

4

CJam, 16 10 byte

Cảm ơn jimmy23013 vì đã lưu 6 byte.

N{eam*_o}h

Đầu vào là một đối số dòng lệnh cho mỗi ký tự. Đầu ra là một chuỗi trên mỗi dòng.

Hãy thử trực tuyến! (Nhưng giết nó ngay lập tức ...)

Giải trình

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

Bình thường, 7 byte

.V0j^zb

Thay thế cho @fry. Chương trình này đọc một chuỗi và tiếp tục in chuỗi cho đến vô cùng.

Giải trình:

.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

Ngoài ra, sau đây cũng sẽ làm việc. Một chút hacky mặc dù.

u
M^zH7

3

Haskell, 33 byte

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

Đối với exampe, k "xyz"là danh sách vô hạn["","x","y","z","xx","xy","xz","yx","yy","yz","zx","zy","zz","xxx",...]


3

MATL , 10 byte

0cD`G@Z^DT

Hãy thử trực tuyến!Nhưng đừng để nó chạy lâu, để tránh tải tính toán lớn trên máy chủ.

Chương trình hiển thị các chuỗi động, mỗi chuỗi trên một dòng khác nhau.

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

Trăn 3, 95

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

Tại sao các hàm itertools phải có tên dài như vậy.


3
combinations_with_replacementkhông bao giờ có giá trị nó. Tôi khá chắc chắn rằng nó ngắn hơn để sử dụng các vòng lặp. Luôn luôn.
mbomb007

2

Ruby, 65 60 byte

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

Tên dựng sẵn dài như vậy ...


1
AFAIK Bạn không cần không gian trước & & bạn có thể sử dụng p thay vì đặt.
Vụ kiện của Quỹ Monica

@QPaysTaxes Không gian có thể bị hủy và pgọi inspectcác đối số của nó sẽ tạo ra kết quả như[] ["a","b"] ["aa", "ab", ...
Doorknob

Tôi đã hiểu nhầm câu trả lời của bạn. Tôi nghĩ rằng nó đã tạo ra một mảng vô hạn và in nó. Tuy nhiên, tôi khá chắc chắn rằng trên Array, to_s được đặt bí danh để kiểm tra, do đó, đặt và p có cùng một đầu ra. ruby-doc.org/core-2.2.0/Array.html#method-i-to_s WRT không gian: Bạn đã kiểm tra chưa? Phải thừa nhận rằng tôi không chắc chắn, nhưng tôi khá chắc chắn về điều đó.
Vụ kiện của Quỹ Monica

1

Pyke (cam kết 31), 10 9 byte

=blR.fbtp

Giải trình:

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

Luồng lười là khá tốt cho loại điều này.


1

Japt, 50 40 34 28 byte

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

Đầu vào là "string", number of items. Đầu ra được sắp xếp theo chiều dài, sau đó đảo ngược thứ tự bảng chữ cái. Kiểm tra nó trực tuyến!

Làm thế nào nó hoạt động

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.

Phiên bản này sẽ mất một lúc nếu bạn muốn làm hơn 100 mục. Nếu bạn muốn có phiên bản nhanh hơn, hãy thử bản 32 byte này :

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

1

Quế Gum, 6 byte

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

Không cạnh tranh vì Cinnamon Gum đã được thực hiện sau thử thách này.

Dùng thử trực tuyến (TIO giới hạn đầu ra).

Giải trình

Việc hđặt Cinnamon Gum ở định dạng và chế độ tạo . Phần còn lại của chuỗi giải nén thành [%s]*. Sau %sđó, nó được thay thế bằng đầu vào và một trình tạo được tạo ra đầu ra tất cả các chuỗi có thể phù hợp với biểu thức chính quy.


1

05AB1E , 9 byte

g<∞*εÅв¦J

Hãy thử trực tuyến!

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 byte

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

Thời gian này dài hơn giải pháp 53 byte của frageum , nhưng nó minh họa một phương pháp khác với đầu ra được in. Danh sáchl được cập nhật trong khi nó được lặp đi lặp lại, bằng cách nối thêm mỗi hậu tố một ký tự của mỗi chuỗi được đọc.

Nó cũng dài như vậy để sử dụng map:

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

Độ dài tương tự có thể được thực hiện trong Python 3, mất char print()và lưu một cái bằng cách giải nén đầu vào.

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

0

Zsh , 31 byte

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

Hãy thử trực tuyến!

In mảng, sau đó nén vào các đối số trước khi đệ quy. Mặc dù bao gồm tên hàm, đây là một byte ngắn hơn phiên bản lặp:

for ((;;))<<<${(F)a}&&a=($^a$^@)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.