Super permutations

20

6

Super permutations

Input: A string
The program should loop through all lengths of the input (decrementing one each time), generate all combinations with replacement of the string, then make permutations out of the generated combinations, and display all of the strings. They can be separated with anything (doesn't need to be a comma)

Example for the string 'abc':

a, b, c, aa, ab, ac, ba, bb, bc, ca, cb, cc
aaa, aab, aac, aba, abb, abc, aca, acb, acc
baa, bab, bac, bba, bbb, bbc, bca, bcb, bcc
caa, cab, cac, cba, cbb, cbc, cca, ccb, ccc

The values don't necessarily have to be sorted.
Avoid any standard loop holes.

InxaneNinja

Posted 2020-01-25T11:42:19.147

Reputation: 328

6Can we also include the empty string as a length zero permutation? – Jo King – 2020-01-25T13:02:37.003

7Will the string contain duplicates? If so, do you need the output to be deduplicated? – Neil – 2020-01-25T16:31:39.567

1I tagged this code golf, because all the answers are assuming it is. – xnor – 2020-01-25T18:57:20.153

9

I'm finding the talk of permutations and combinations confusing here. The way I'd phrase the task is: output all strings made of characters in the input, whose length ranges from 1 to the length of the input. Related: Output all strings.

– xnor – 2020-01-25T18:59:59.823

1Can we take a length argument? – S.S. Anne – 2020-01-26T14:09:39.887

Can we output a list of lists? Like [[a,b], [aa,ab,ba,bb]]? Some answers already assume this, while others flatten the list – Jo King – 2020-01-28T01:28:03.513

Answers

13

Scratch 3.0, 65 blocks / 637 632 bytes

Part 1

Part 2

Part 3

Part 4

Look at y'all, having fun with your fancy shmancy permutation functions/map tools. Well, not I! No, not I! When using Scratch, one has to do things themselves! You won't find any built-ins around these parts! I'm just glad there still ain't any gotos ;)

But more seriously, the image is split into 4 parts because it's just soooo long Press space to clear the lists before each run

And finally,

Try it online Scratch!

As SB Syntax:

when gf clicked
set[c v]to(0
ask()and wait
set[L v]to(length of(answer
add(1)to[b v
repeat((L)-(1
add(0)to[b v
end
repeat until<(c)=(1
set[s v]to(0
set[l v]to(1
repeat(length of[b v
change[s v]by(item(l)of[b v
change[l v]by(1
end
if<(s)=((L)*(L))>then
set[c v]to(1
end
set[r v]to(
set[l v]to(1
repeat(length of[b v
set[r v]to(join(r)(letter(item(i)of[b v])of(answer
change[i v]by(1
end
add(r)to[o v
replace item(1)of[b v]with((item(1)of[b v])+(1
set[j v]to(1
repeat(length of[b v
if<(item(j)of[b v])>(length of(answer))>then
replace item(j)of[b v]with(1
replace item((j)+(1))of[b v]with((item((j)+(1))of[b v])+(1
end
change[j v]by(1

-5 bytes due to not being a silly billy and removing extranous spaces

Lyxal

Posted 2020-01-25T11:42:19.147

Reputation: 5 253

8

05AB1E, 4 3 bytes

-1 byte thanks to a'_'

ā€ã

Try it online!

Grimmy

Posted 2020-01-25T11:42:19.147

Reputation: 12 521

6

I don't know 05AB1E. I just randomly pasted a character inside the program. And it WORKS!?

– None – 2020-01-25T13:59:47.970

@a'_' you what? That sounds insanely unlikely lol – Cruncher – 2020-01-28T14:21:39.697

@Cruncher I am serious. I thought turning the gL into ã (i.e. a double-cartesian power) would work. It turns out that I copied the wrong character (ā indeed looks very similar to ã) – None – 2020-01-28T14:24:15.380

(And then I feel that pretending that I don't know 05AB1E and saying randomly will make viewers laugh harder.) – None – 2020-01-28T14:33:57.577

7

Jelly, 2 bytes

ṗJ

A monadic Link which accepts a list of characters and returns a list of lists of lists of characters.

Try it online! (footer formats as a grid)

How?

ṗJ - list, S
 J - range of length of S
ṗ  - Cartesian power (vectorises)

If we must output a flat list of "strings" (lists of characters) we can add (tighten) for the cost of a byte.

Jonathan Allan

Posted 2020-01-25T11:42:19.147

Reputation: 67 804

6

Haskell, 34 bytes

f s=init$mapM(\_->s)=<<scanr(:)[]s

Try it online!

Here's how it works, using input s="abc":

                       scanr(:)[]s

Produces the suffixes of s, ["abc","bc","c",""], by prepending each character in turn to the front and tracking the intermediate results.

         mapM(\_->s)

Uses the list monad to map each element to s, that is, 'xy'-> ["abc","abc"], and take multiply them as a Cartesian product, here giving ["aa","ab","ac","ba","bb","bc","ca","cb","cc"].

         mapM(\_->s)=<<scanr(:)[]s

Uses =<< as concatMap to take the function above that uses mapM and apply it to each of the suffixes, thereby producing the Cartesian products of copies of s numbering from 0 to its length, in a single list.

    init$

Removes the empty string, produces from the suffix of length 0.

f s=

Declares the function.

xnor

Posted 2020-01-25T11:42:19.147

Reputation: 115 687

What is going on here? – RGS – 2020-01-25T21:57:01.413

Thanks for the explanation! – RGS – 2020-01-27T18:36:28.683

5

05AB1E, 6 bytes

gENIã)

Try it online!

Explanation

gENIã)
 E     # foreach in...
g      # the input
    ã  # find the cartesian product of...
   I   # the input...
  N    # repeat N
     ) # wrap the final stack to an array
       # implicit output of the top element

mabel

Posted 2020-01-25T11:42:19.147

Reputation: 1 489

14That looks like genial, which in my (natural) language means brilliant. +1 for that – RGS – 2020-01-25T12:18:51.513

3

J, 16 bytes

a:-.~[:,#\{@#"{<

Try it online!

  • a:-.~ Remove empty boxes from...
  • [:, The flatten of...
  • {@#"{ The Catalog (cross prod) of {@...
  • #\{@#"{<
    • < The boxed input...
    • #"{ Copied this many times...
    • #\ 1, 2, ... N, where N is the input length. That is, we copy the input once, then twice, ... then N times, taking the Catalog of each of those.

Jonah

Posted 2020-01-25T11:42:19.147

Reputation: 8 729

3

PHP, 176 174 173 171 170 166 bytes

$c=$t=count($u=array_values(array_unique(str_split($argn))));for($s=1;$i<$t**$t;){$i-$c?:[$s++,$c*=$t,$i=0];for($k=$i++,$j=0;$j<$s;$j++,$k/=$t)echo$u[$k%$t];echo',';}

Try it online!

-4 bytes thanks to @Ismael Miguel.

Method: simply count in base N, where N is the number of unique characters in the input string.

Guillermo Phillips

Posted 2020-01-25T11:42:19.147

Reputation: 561

You can save 2 bytes by moving $k/=$t; into the for($j=0;$j<$s;$j++), and remove the {...}, like this: for($j=0;$j<$s;$j++,$k/=$t)echo$u[$k%$t]; – Ismael Miguel – 2020-01-27T09:30:42.070

Didn't think PHP supported the comma operator. But yes, in for loops! – Guillermo Phillips – 2020-01-27T09:51:23.743

Oh, it works. And here's something else: you can replace your if($i==$c){$s++;$c*=$t;$k=$i=0;} with $i==$c?[$s++,$c*=$t,$k=$i=0]:0;. This will save 1 byte, and work the same. This uses a ternary operator and an array, where the array will be "executed" if the condition is true. However, you need to have a value for the false condition (the 0). What saves the byte is really the array, because you remove the ; after the 3rd assignment, when changing the syntax.

– Ismael Miguel – 2020-01-27T10:04:21.100

1Very clever, I shall use it in future. I switched the condition however, for one extra byte: $i!=$c?:[$s++,$c*=$t,$k=$i=0]; – Guillermo Phillips – 2020-01-27T10:18:12.270

That is actually really clever. I didn't though about it. But hey, 5 bytes shaved from the total is pretty good. – Ismael Miguel – 2020-01-27T10:24:51.727

3

PowerShell, 42 bytes

($a=$args)|%{($p=$p|%{$t=$_;$a|%{$t+$_}})}

Try it online.

Expects input via splatting.

Andrei Odegov

Posted 2020-01-25T11:42:19.147

Reputation: 939

via $null. it's smart! – mazzy – 2020-01-27T08:20:56.513

2

Python 3, 95 bytes

import itertools as i;lambda s:[''.join(p)for l in range(len(s))for p in i.product(s,repeat=l)]

Try it online

RGS

Posted 2020-01-25T11:42:19.147

Reputation: 5 047

1Using l here made me confuse it with 1 for a second back in the repeat= part... +1! – ojdo – 2020-01-27T11:51:06.753

@ojdo maybe not the best choice on my part :P – RGS – 2020-01-27T12:37:21.063

Note: you can format your TIO code like this for anonymous lambdas with imports

– Jo King – 2020-01-29T23:26:47.410

@JoKing That does look better! Thanks! – RGS – 2020-01-29T23:34:37.053

2

Burlesque,  5  4 bytes

sacb

Try it online!

-1 thanks to DeathIncarnate!

sa    # Duplicate the input and get it's length
  cb  # Get all combinations of the input characters up to the length of the input

Mintable

Posted 2020-01-25T11:42:19.147

Reputation: 21

sa is shorthand for JL[ Try it online!

– DeathIncarnate – 2020-02-04T20:29:30.197

2

Python 2, 69 68 bytes

f=lambda s,A={''}:s in A and A or f(s,A|{a+c for a in A for c in s})

Try it online!

Outputs a set; includes the empty string.

Python 2, 71 bytes

f=lambda s,A=[]:s in A and A or f(s,set(s)|{a+c for a in A for c in s})

Try it online!

If empty string is not allowed...

Chas Brown

Posted 2020-01-25T11:42:19.147

Reputation: 8 959

2

JavaScript (ES7), 90 bytes

Returns a Set.

s=>new Set([...Array(n=(L=-~s.length)**~-L)].map(_=>(g=n=>n?[s[n%L-1]]+g(n/L|0):'')(n--)))

Try it online!

Commented

s => new Set(            // build a set from
  [...Array(             //   an array of
    n =                  //   n entries, with:
      (L = -~s.length)   //     n = L ** (L - 1)
      ** ~-L             //     where L is the length of s + 1
  )]                     //   
  .map(_ =>              //   for each entry:
    ( g = n =>           //     g is a recursive function taking n
        n ?              //       if n is not equal to 0:
          [s[n % L - 1]] //         output s[(n mod L) - 1]
                         //         or an empty string if it's undefined
          + g(n / L | 0) //         recursive call with floor(n / L)
        :                //       else:
          ''             //         stop recursion
    )(n--)               //     initial call to g; decrement n afterwards
  )                      //   end of map()
)                        // end of Set()

Arnauld

Posted 2020-01-25T11:42:19.147

Reputation: 111 334

2

Charcoal, 17 bytes

FEθXLθ⊕κEι✂⍘⁺ικθ¹

Try it online! Link is to verbose version of code. Explanation:

FEθXLθ⊕κ

Loop over the substring lengths and raise the length to each power in turn.

Eι✂⍘⁺ικθ¹

Loop from each power to double its value and perform base conversion using the input string as the alphabet, then slice off the first character.

Neil

Posted 2020-01-25T11:42:19.147

Reputation: 95 035

2

Husk, 4 bytes

Total Husk novice, there may be better ways to golf this.

Mπŀ¹

Try it online!

Explanation

  ŀ¹ Find the range [1, ..., len(input)]
Mπ   Map with cartesian power of input

user85052

Posted 2020-01-25T11:42:19.147

Reputation:

1

Perl 6, 32 bytes

{flat [\X~] '',|[xx] .comb xx 2}

Try it online!

Anonymous code block that takes a string and returns a list of string including the length zero permutation.

Jo King

Posted 2020-01-25T11:42:19.147

Reputation: 38 234

1

Pyth, 5 bytes

^LQSl

Try it here!

Mr. Xcoder

Posted 2020-01-25T11:42:19.147

Reputation: 39 774

1

Ruby, 60 bytes

->s{a,*z=s.chars,'';z.product(*a.map{a+z}).map(&:join)-z|[]}

Try it online!

G B

Posted 2020-01-25T11:42:19.147

Reputation: 11 099

0

R, 112 bytes

function(S,s=sapply)cat(unlist(s(1:nchar(S),function(X)do.call('paste0',expand.grid(s(rep(S,X),strsplit,''))))))

Try it online!

Things that make you go Argh, strings in R.

Expands out to the following

cat(                                           # output the results
  unlist(                                      # collapse the list
    sapply(1:nchar(S),                         # for 1 to character length of S
      function(X)do.call('paste0',             # for each row from the grid paste characters together
         expand.grid(                          # create permutations 
           sapply(rep(S,X),strsplit,''))))))   # replicate the string X times and split.

So we produce a lists of [['a','b','c']], [['a','b','c'],['a','b','c']], [['a','b','c'],['a','b','c'],['a','b','c']]. These are feed into expand.grid to produce the permutations.

Each row of the grid is pasted together with no gaps in the do.call.

As it is still in a list we apply unlist so that cat will be able to output it.

MickyT

Posted 2020-01-25T11:42:19.147

Reputation: 11 735

depending on whether you are allowed to output the list directly (it's asked in comments but as yet unanswered) you could replace cat(unlist(...)) with print(...) (maybe show(...) will work also — haven't tried) – JDL – 2020-01-28T14:14:45.940

I could probably just get rid of them completely. There could also be an argument put forward to remove the do.call – MickyT – 2020-01-28T18:08:21.110

0

Perl 5 -lF, 48 bytes

$"=',';map$k{$_}++||say,glob"{@F}"."{@F,''}"x$#F

Try it online!

Xcali

Posted 2020-01-25T11:42:19.147

Reputation: 7 671