Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given a set of letters, output all strings made of those letters. (This is Kleene star of the set.) For example, for {'a','b'}, the strings are:

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

Input: A non-empty collection of distinct letters a..z. These may be characters or single-character strings.

Output: All strings in those letters, in any order, without repeats. You may use lists of chars as strings.

This is an infinite list, so you can output it by:

  • Running forever writing more and more strings. These strings can be written in any flat separated format, meaning that they you can tell where each string ends, but the strings aren't subdivided into groups.
  • Taking a number n as input and outputting the first n strings in any flat separated format
  • Yielding each string in turn from a generator object
  • Producing an infinite object

Be sure that your method eventually produces every string in the output, since it's possible to produce infinitely many strings from the set while never getting to some strings.

You may not output it by

  • Producing the nth string given n
  • Providing a membership oracle that decides if a given string belongs to the set

Built-ins are allowed, but I ask voters to give attention to answers that implement the operation themselves over ones that mostly rely on a built-in.

var QUESTION_ID=74273,OVERRIDE_USER=20260;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/74273/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

share|improve this question
    
@Cyoce Not sure what you mean. I clarified that the strings must be separated, so you can tell the empty string from nothing. – xnor Feb 26 at 20:54
    
Please explain why "producing the Nth string given N" is not allowed. – CalculatorFeline Feb 26 at 21:02
4  
@CatsAreFluffy It was a judgment call. I think producing the Nth string would be too easy compared to the alternatives and make the challenge less interesting, especially because some languages have built-in arbitrary-base conversion. Also, I didn't think it captured the idea of generating an infinite set rather than querying it. – xnor Feb 26 at 21:04
    
Can you explain "producing an infinite object"? Does that mean we can for example push each string onto the stack (for stack languages) and let it run "forever", even if no output will ever be produced because the program won't finish? – Luis Mendo Feb 26 at 21:55
    
@DonMuesli Is output to the stack an accepted output method for such languages? And, will the stack contain only these strings at any point in time? – xnor Feb 26 at 21:58

19 Answers 19

Python 2, 53 56

-3 after realizing that yield x can be used as an expression.

def f(s):yield'';[(yield w+c)for w in f(s)for c in s]
share|improve this answer
    
One byte shorter, but starts at 'aa' rather than at '': S=lambda s:(c+w for f in[str,S]for w in f(s)for c in s). Also doesn't work for the empty input. – orlp Feb 27 at 0:50

Haskell, 24 bytes

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

Produces an infinite list.

*Main> f "abc"
["","a","b","c","aa","ba","ca","ab","bb","cb","ac","bc","cc","aaa","baa","caa","aba","bba","cba",…
share|improve this answer
    
Too bad (:)<$>s<*>f s would give the wrong order. There's f s="":(flip(:)<$>f s<*>s) but it's longer. – xnor Mar 1 at 0:05
    
Yeah. I had found the 23-byte f s=[]:(f s<**>map(:)s) except that <**> isn’t in Prelude. – Anders Kaseorg Mar 1 at 6:58

JavaScript (ES6), 61 bytes

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

Port of @feersum's Python generator. The let is necessary. Save 2 bytes by using an array comprehension (ES7 proposal, requires Firefox 30 or later):

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

Alternative version for 73 bytes that returns the first n elements yielded by the above generator:

(s,n)=>Array(n).fill('').map(g=(r,i)=>i--?g(r+s[i%l],i/l|0):r,l=s.length)
share|improve this answer
    
JS has generators? :0000000 – cat Feb 29 at 16:46

Mathematica, 32 31 Bytes

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

Edit:

CatsAreFluffy scraped off one byte.

share|improve this answer

Perl, 39 37 35 bytes

(First describes an older version. The new shorter program is at the end)

Includes +3 for -alp

Run with the set of characters on STDIN, e.g. perl -alp kleene.pl <<< "a b c"

kleene.pl (this version is 34+3 bytes):

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

Add +2 for -F (drop implicit -a if no spaces between input characters, or -6 (only @a="" before }) if we already put commas between the characters on STDIN

Explanation:

The -alp options make the code effectively:

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

As you can see <> in perl is not only used for readline, but can also do shell style globbing (in fact in ancient perls it was implemented by calling the shell).

For example <{a,b}{1,2}> will expand to "a1","a2","b1","b2"

So if we have the elements in @F we just need to add commas inbetween. The default inbetween character for interpolation is space, which is stored in special variable $". So setting $" to , will turn "{@F}" into {a,b} if @F=qw(a b) (globs expand as strings)

In fact I would really have liked to loop with something like glob"{@F}"x$n++, but I kept running into the problem that the first empty line doesn't get generated and all workarounds I found made the code too long.

So another essential part of this code is that if you use a for to loop over an array you can actually push extra elements on it during the loop and the loop will also pick up these new elements. So if in the loop we are e.g. at element "ab", then <{@F}$_> will expand to <{a,b}ab> which in list context becomes ("aab", "bab"). So if I push these on @a then the strings extended one to the left become available too

All I still need to do is prime the loop with an empty string. That is done using$#a = 0 (, in numeric context becomes 0) which causes the first and only element of @a to become undef which will behave like "" when I use it

Improvement

In fact by doing tests for this explanation I found a short way to use a growing glob that properly handles the first empty entry. Run as perl -ap kleene0.pl <<< "a b" (so add 2 bytes for -ap)

kleene0.pl (this version is 33+2 bytes):

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

All these solutions will keep more and more of the output in memory and that will cause the program to fail after some time. You can also use perl globs for lazy generation by using them in scalar context, but that makes the programs longer....

share|improve this answer
    
Can you please explain what is going on around:<{@F}$_>? Thanks! – andlrc Feb 28 at 1:50

Pyth, 7

<s^LzQQ

Try it here

This computes the cartesian product of the input with each number from 0..n-1, joins them, and then only keeps the first n. This will time out online for numbers or strings that are much bigger than 3-4.

Alternatively, to get infinite output look at Jakube's answer.

share|improve this answer

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
share|improve this answer
    
Wow. Shorter and without builtins. – Morgan Thrapp Feb 26 at 21:33

CJam, 16 10 bytes

Thanks to jimmy23013 for saving 6 bytes.

N{eam*_o}h

Input is one command-line argument per character. Output is one string on each line.

Try it online! (But kill it immediately...)

Explanation

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
share|improve this answer

Pyth, 7 bytes

.V0j^zb

Alternative to @fry. This program reads a string and keeps on printing strings until infinity.

Explanation:

.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

Alternatively the following will also work. A little bit more hacky though.

u
M^zH7
share|improve this answer

Haskell, 33 bytes

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

For exampe, k "xyz" is the infinite list ["","x","y","z","xx","xy","xz","yx","yy","yz","zx","zy","zz","xxx",...]

share|improve this answer

MATL, 10 bytes

0cD`G@Z^DT

Try it online! But don't leave it running for long, to avoid large computational load on the server.

The program displays the strings dynamically, each string on a different line.

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
share|improve this answer

Jelly, 8 6 bytes

⁷³p$Ȯ¿

This is a monadic link that accepts an alphabet and prints an infinite list of strings. Try it online!

How it works

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

Alternate version, 6 bytes (non-competing)

R’ḃL}ị

This is a dyadic link that accepts an alphabet and the desired number of strings as left and right arguments, respectively.

I consider this version non-competing, since it uses bijective base conversion, which has been implemented after this challenge had been sandboxed. Try it online!

How it works

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.
share|improve this answer

Python 3, 95

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

Why must itertools functions have such long names.

share|improve this answer
3  
combinations_with_replacement is never worth it. I'm pretty sure it's shorter to use loops. Always. – mbomb007 Feb 26 at 22:37

Ruby, 65 60 bytes

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

Such long builtin names...

share|improve this answer
1  
AFAIK You don't need the space before & and you can use p instead of puts. – QPaysTaxes Feb 26 at 22:56
    
@QPaysTaxes The space cannot be dropped, and p calls inspect on its arguments which would produce output like [] ["a","b"] ["aa", "ab", ... – Doorknob Feb 27 at 6:15
    
I misunderstood your answer. I thought it was generating an infinite array and printing it. However, I'm fairly sure that on Array, to_s is aliased to inspect, so puts and p have the same output. ruby-doc.org/core-2.2.0/Array.html#method-i-to_s WRT the space: Did you check? Admittedly I'm not certain, but I'm fairly sure about it. – QPaysTaxes Feb 27 at 12:39

Pyke (commit 31), 10 9 bytes

=blR.fbtp

Explanation:

=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(^)
share|improve this answer

Scala, 69

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

Lazy streams are quite nice for this kind of thing.

share|improve this answer

Japt, 50 40 34 28 bytes

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

Input is "string", number of items. Output is sorted by length, then reverse alphabet order. Test it online!

How it works

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.

This version takes a while if you want to do any more than 100 items. If you want a faster version, try this 32-byte one:

V*2 o ms1+Ul)f@!Xf'0î£UgXnH}ïV
share|improve this answer

Python, 55 bytes

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

This is longer than feersum's 53-byte solution, but it illustrates a different method with printed output. The list l is updated while it is iterated over, by appending every one-character suffix of each string that is read.

It's equally long to use map:

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

The same length can be done in Python 3, losing a char for print(), and saving one by input unpacking.

s,*l=input(),''
for x in l:print(x);l+=[x+c for c in s]
share|improve this answer

Cinnamon Gum, 6 bytes

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

Non-competing because Cinnamon Gum was made after this challenge.

Try it online (TIO limits output).

Explanation

The h puts Cinnamon Gum in format and generate mode. The rest of the string decompresses to [%s]*. The %s is then replaced with the input, and a generator is created that outputs all possible strings matching the regex.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.