Створіть набір перестановок, що додаються, в лексикографічно відсортованому порядку


14

Визначте послідовність доповнення, що додається, довжиною, nщоб бути перестановкою чисел, 1, 2, ..., nякі можуть бути згенеровані наступною процедурою:

  • Почніть з числа 1.

  • Для кожного номера від 2до n, помістити це число на початку або в кінці послідовності (або Prepend або на додавання його, звідси і назва послідовності).

Наприклад, це правильний спосіб генерування послідовності додавання додавання довжиною 4:

1
21     [beginning]
213    [end]
2134   [end]

Ваше завдання - створити програму або функцію, яка буде приймати число nвід 3до 30введення, та роздрукувати або повернути всі послідовності перед додаванням додавання довжини nв лексикографічному порядку (якщо ви виводите рядки, а не списки, цифри вище 9 будуть представлені як літери a-u, щоб зберегти довжину рядка). Наприклад, це такий порядок для n = 4:

1234  [RRR]
2134  [LRR]
3124  [RLR]
3214  [LLR]
4123  [RRL]
4213  [LRL]
4312  [RLL]
4321  [LLL]

Загалом, існує 2 n-1 перестановки, додані до перестановки довжини n.

Ви не можете використовувати будь-які вбудовані функції сортування на вашій мові у своєму коді. Виграє найкоротша програма для виконання будь-якої мови.


Я не прихильник вимоги до вихідного формату, зокрема перетворення в літери a-u. Чи можемо ми просто вивести списки чисел?
xnor

3
Можливо, ви захочете прийняти відповідь через деякий час, оскільки деякі люди, як правило, не відповідають на запитання, якщо він має прийняту відповідь.
Оптимізатор

1
Отже, ви неправильно прийняли відповідь ..
Оптимізатор

2
FryAmTheEggman опублікував свою відповідь за 21 хвилину до того, як ви відредагували свою.
Джо З.

2
@Optimizer Я не зовсім думаю, що це найсмішніший спосіб - відповідь FryAmTheEggman була 19 байтів за 21 хвилину до вашого. Це робить його якнайшвидшою найкоротшою відповіддю.
Джо З.

Відповіді:


10

CJam, 22 20 19 17 байт

]]l~{)f+_1fm>|}/p

Розширення коду :

]]                   "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";

Як це працює :

Це налагоджена версія коду:

]]l~ed{)edf+ed_ed1fm>ed|ed}/edp

Давайте подивимося, як це працює для введення даних 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>|}/";

Спробуйте його онлайн тут


6

Haskell, 47 байт

f 1=[[1]]
f n=(\x->map(++[n])x++map(n:)x)$f$n-1

1
Перехід до розуміння списку економить кілька байтів: f n=[[n:x,x++[n]]|x<-f$n-1]>>=id(використовуючи функцію кодексу гольфістів concat >>=id).
німі

1
@nimi, але це в неправильному порядку r
гордий haskeller

@proudhaskeller: Дорогий, не прочитав специфікацію уважно. Я спробував виправити це і знайшов чотири трохи різні способи однакової довжини, як і версія @ alephalpha, тому не можу запропонувати поліпшення. f n=[x++[n]|x<-f$n-1]++[n:x|x<-f$n-1], f n=map(++[n])(f$n-1)++[n:x|x<-f$n-1], f n=map(++[n])(f$n-1)++map(n:)(f$n-1),f n=(++[n])#n++(n:)#n;p#i=map p$f$i-1
Ними

5

Пітон 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)]

Виводить список списків чисел.

Рекурсивне рішення. Для n==1, вихід [[1]]. В іншому випадку додайте nдо початку або в кінці всіх (n-1)-перевірок. Попередження робить перестановку лексикографічно пізніше, ніж додавання, тому перестановки залишаються відсортованими.

"Булева" bкодує, чи слід ставити її [n]на початку чи в кінці. Власне, ми переміщуємо решту списку xу виразі x*b+[n]+x*-b. Поставлення bяк -1або 1дозволяє використовувати фліп шляхом відмови, оскільки список, помножений на, -1є порожнім списком.


4

Піта, 19

usCm,+dH+HdGr2hQ]]1

Спробуйте його онлайн тут

Це повна програма, яка приймає дані від stdin.

Це працює аналогічно рішенню xnor, але генерує значення трохи поза порядком, тому вони повинні бути упорядковані. Що відбувається на кожному рівні, це те, що кожен попередній список значень має нову додану цінність до кінця та на початку, і всі вони загорнуті у 2-х кортеж, які загорнуті у список. Наприклад, перший крок робить це:

[[1]]
[([1,2], [2,1])]

Потім цей список кортежів накопичується (а потім підсумовується, щоб видалити самий зовнішній список). У першому випадку це просто дає розгорнуте значення зверху, оскільки у списку є лише одне значення.

Кроки, що показують 2-> 3:

([1,2], [2,1])
[([1,2,3],[3,1,2]),([2,1,3],[3,2,1])]
([1,2,3],[2,1,3],[3,1,2],[3,2,1])

2

Математика, 57 54 49 байт

f@1={{1}};f@n_:=#@n/@f[n-1]&/@Append~Join~Prepend

Приклад:

f[4]

{{1, 2, 3, 4}, {2, 1, 3, 4}, {3, 1, 2, 4}, {3, 2, 1, 4}, {4, 1, 2, 3} , {4, 2, 1, 3}, {4, 3, 1, 2}, {4, 3, 2, 1}}


2

J, 26 байт

   0|:<:((,,.,~)1+#)@[&0,.@1:

   (0|:<:((,,.,~)1+#)@[&0,.@1:) 3
1 2 3
2 1 3
3 1 2
3 2 1

Поліпшення в 1 байті завдяки FUZxxl .


Заміна ,.для ,"1одного персонажа.
FUZxxl

1

Pyth, 34 33 31 29

В основному переклад XNOR «s відповідь на Python . Я все ще не чудовий з Pyth, тому пропозиції щодо вдосконалення вітаються.

Визначає функцію yповернення списку списків цілих чисел.

L?]]1<b2smm++*kdb*k_dy-b1,1_1

Оновлення: збережено 2 байти завдяки FryAmTheEggman .

Пояснення:

L                                  define a function y with argument b that returns
 ?*]]1<b2                          [[1]] if b < 2 else
         s                         sum(
          m                        map(lambda d:
           m                       map(lambda k:
            ++*kdb*k_d             k*d + [b] + k*-d
                      y-b1         , y(b - 1))
                          ,1_1)    , (1, -1))

Деякі матеріали pyth: -b1можуть бути tb, [1_1)можуть бути ,1_1(однак ви можете просто опустити закриту дужку, оскільки вам потрібно лише порахувати байти, необхідні для створення функції, хоча ви не зможете викликати її, не закриваючи її), і ви не потрібно загортати bсписок, оскільки pyth автоматично перетворюється на список при додаванні списку до int.
FryAmTheEggman

Я придумав спосіб зберегти кілька байтів, вручну зробивши другу карту [1,-1]. Я можу зберегти байти для жорсткого кодування чогось короткого, особливо коли ви спрощуєте логіку. Я отримуюL?]]1<b2sCm,+db+bdytb
FryAmTheEggman

@FryAmTheEggman Ви можете насправді додати це як власну відповідь. Це просто приголомшливо.
PurkkaKoodari

Гаразд, я хотів спробувати перемогти CJam перед публікацією, але, мабуть, поштовий трюк досить цікавий, щоб заслужити його публікацію. Удачі з Pyth;)
FryAmTheEggman

1

Чистий Баш, 103

Довше, ніж я сподівався:

a=1..1
for i in {2..9} {a..u};{
((++c<$1))||break
a={${a// /,}}
a=`eval echo $a$i $i$a`
}
echo ${a%%.*}

1

JavaScript (ES6) 73 80

Реалізація JavaScript приємного рішення @ Optimizer.

Рекурсивний (73):

R=(n,i=1,r=[[1]])=>++i>n?r:r.map(e=>r.push([i,...e])+e.push(i))&&R(n,i,r)

Ітеративний (74):

F=n=>(i=>{for(r=[[1]];++i<=n;)r.map(e=>r.push([i,...e])+e.push(i))})(1)||r

Тест у консолі Firefox / FireBug

R(4)

[[1, 2, 3, 4], [2, 1, 3, 4], [3, 1, 2, 4], [3, 2, 1, 4], [4, 1, 2, 3] , [4, 2, 1, 3], [4, 3, 1, 2], [4, 3, 2, 1]]


0

Моє рішення Java:

public static void main(String[] args) {
    listPrependAppend(4);
}

private static void listPrependAppend(int n) {
    int total = (int) Math.pow(2, n - 1);
    int ps;
    boolean append;
    String sequence;
    String pattern;

    for (int num = 0; num < total; num++) {
        sequence = "";
        pattern = "";
        append = false;
        ps = num;
        for (int pos = 1; pos < n + 1; pos++) {
            sequence = append ? (pos + sequence) : (sequence + pos);
            append = (ps & 0x01) == 0x01;
            ps = ps >> 1;
            if (pos < n) {
                pattern += append ? "L" : "R";
            }
        }
        System.out.format("%s\t[%s]%n", sequence, pattern);
    }
}

О, бач, зараз, побачивши інші відповіді, я бачу, що ви маєте на увазі про найкоротшу відповідь.
Бретт Райан

2
Хоча ваше рішення є респектабельним, стислим і добре представленим власним правом, ви правильні, що це не зовсім кандидат на проблему.
Джо З.

1
@BrettRyan Ви можете зробити свій код значно коротшим, видаливши зайві пробіли та використовуючи одноіменні імена змінних. Ви також можете замінитиfalse чимось на кшталт 5<4.
ProgramFOX

1
Дякую, хлопці. Це була моя перша спроба брати участь у викликах коду. Я просто шукав деякі проблеми програмування і не усвідомлював, що мета полягає в тому, щоб отримати найкоротше рішення. :) Дякую за те, що дозволили мені брати участь.
Бретт Райан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.