Generate the set of prepend-append permutations in lexicographically sorted order
CJam, 22 20 19 17 bytes
]]l~{)f+_1fm>|}/p
Code expansion:
]] "Put [[]] onto stack. What we will do with this array of array is";
"that in each iteration below, we will first append the next";
"number to all present arrays, then copy all the arrays and";
"move the last element to first in the copy";
l~ "Read input number. Lets call it N";
{ }/ "Run this code block N times ranging from 0 to N - 1";
)f+ "Since the number on stack starts from 0, add 1 to it and append";
"it to all arrays in the array of array beginning with [[]]";
_1fm> "Copy the array of array and move last element from all arrays";
"to their beginning";
| "Take set union of the two arrays, thus joining them and eliminating";
"duplicates. Since we started with and empty array and started adding";
"numbers from 1 instead of 2, [1] would have appeared twice if we had";
"simply done a concat";
p "Print the array of arrays";
How it works:
This is a debug version of the code:
]]l~ed{)edf+ed_ed1fm>ed|ed}/edp
Let's see how it works for input 3
:
[[[]] 3] "]]l~" "Empty array of array and input";
[[[]] 1] "{)" "First iteration, increment 0";
[[[1]]] "{)f+" "Append it to all sub arrays";
[[[1]] [[1]]] "{)f+_" "Copy the final array of array";
[[[1]] [[1]]] "{)f+_1fm>" "shift last element of each";
"sub array to the beginning";
[[[1]]] "{)f+_1fm>|}" "Take set based union";
[[[1]] 2] "{)" "2nd iteration. Repeat";
[[[1 2]]] "{)f+"
[[[1 2]] [[1 2]]] "{)f+_";
[[[1 2]] [[2 1]]] "{)f+_1fm>";
[[[1 2] [2 1]]] "{)f+_1fm>|}";
[[[1 2] [2 1]] 3] "{)";
[[[1 2 3] [2 1 3]]] "{)f+"
[[[1 2 3] [2 1 3]] [[1 2 3] [2 1 3]]] "{)f+_";
[[[1 2 3] [2 1 3]] [[3 1 2] [3 2 1]]] "{)f+_1fm>";
[[[1 2 3] [2 1 3] [3 1 2] [3 2 1]]] "{)f+_1fm>|}";
[[[1 2 3] [2 1 3] [3 1 2] [3 2 1]]] "{)f+_1fm>|}/";
Try it online here
Haskell, 47 bytes
f 1=[[1]]
f n=(\x->map(++[n])x++map(n:)x)$f$n-1
Python 2, 68
f=lambda n:[[1]]*(n<2)or[x*b+[n]+x*-b for b in[1,-1]for x in f(n-1)]
Outputs a list of lists of numbers.
A recursive solution. For n==1
, output [[1]]
. Otherwise, add n
to the start or end of all (n-1)
-permutations. Prepending makes the permutation lexicographically later than appending, so the permutations remain sorted.
The "Boolean" b
encodes whether to put [n]
at the start or end. Actually, we move the rest of the list x
in the expression x*b+[n]+x*-b
. Putting b
as -1
or 1
lets use flip by negating, since a list multiplied by -1
is the empty list.