Побудуйте перестановку


9

Для цього завдання ви збираєтеся створити функцію (ваша функція може бути повноцінною програмою), яка приймає список як вхідний і повертає перестановку цього списку. Ваша функція повинна відповідати наступним вимогам.

  • Він повинен бути детермінованим.

  • Складаючи свою функцію із собою змінну кількість разів, слід мати можливість отримати список до будь-якої з її перестановок.

Це питання з кодовим гольфом, тому відповіді будуть набиратись у байтах, менше байтів буде кращим.

Подальші правила

  • Ви можете взяти будь-який тип списку, ( [Integer], [String], [[Integer]]) до тих пір , як це

    • Не може бути порожнім
    • Може містити окремі об'єкти, що мають принаймні 16 можливих значень. (Ви не можете використовувати Haskell [()]і стверджуєте, що ваша функція є id)
    • Може містити повторювані об'єкти (без наборів)
  • Ви можете написати програму або функцію, але повинні відповідати стандартному вводу-виводу.


Але S_nце лише циклічноn<3
Leaky Nun

@LeakyNun, це не прохання про одну перестановку, яка генерує симетричну групу: вона запитує next_permutationфункцію.
Пітер Тейлор

Чи вистачить лише перестановки списків 0-х та 1-х?
xnor

Я не впевнений, що розумію суть цього обмеження. Якщо ви дозволяєте списки булевих, який сенс не дозволяти перетворювати його на два різних пункти?
Денніс

@Денніс Ви добре зазначаєте. Я забороняю списки булевих. Або типи, які мають менше 16 можливих значень.
Ad Hoc Hunter Hunter

Відповіді:


4

CJam (11 байт)

{_e!_@a#(=}

Демонстрація в Інтернеті, що показує повний цикл для списку чотирьох елементів з одним дублюючим елементом.

Розсічення

{      e# Define a block
  _e!  e#   Find all permutations of the input. Note that if there are duplicate
       e#   elements in the input then only distinct permutations are produced.
       e#   Note also that the permutations are always generated in lexicographic
       e#   order, so the order is independent of the input.
  _@a# e#   Find the index of the input in the list
  (=   e#   Decrement and get the corresponding element of the list
       e#   Incrementing would also have worked, but indexing by -1 feels less
       e#   wrong than indexing by the length, and makes this more portable to
       e#   GolfScript if it ever adds a "permutations" built-in
}

2

Mathematica + Combinatorica (вбудований пакет) 34 байт

19 байт для завантаження пакета і 15 для функції.

<<"Combinatorica`";NextPermutation

Використання:

%@{c, b, a}

Без вбудованого 61 байт

Extract[s=Permutations[Sort@#],Mod[s~Position~#+1,Length@s]]&

Combinatorica, як передбачається, повністю включена в Mathematica, але я думаю, що функція NextPermutation була не помічена.



2

C ++, 42 байти

#include <algorithm>
std::next_permutation

Ця точна операція є вбудованим в C ++.


2
Чому простір після #include?
Yytsi

2

JavaScript (ES6), 145 139 137 134 108 байт

Збережено колосальних 25 байт завдяки @Neil!

Вводить дані як масив алфавітних символів. Повертає наступну перестановку як інший масив.

a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,a.concat(a.splice(x+1).sort()))

Як?

Це покоління в лексикографічному порядку, яке обробляє 4 наступні етапи на кожній ітерації:

  1. Знайдіть найбільший індекс X такий, що a [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. Знайдіть найбільший індекс Y більший за X такий, що a [Y]> a [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. Поміняйте значення в [X] з тим з а [Y]

    a[x] = a[y], a[y] = t
  4. Сортуйте послідовність від [X + 1] до та включаючи кінцевий елемент у лексикографічному порядку за зростанням

    a.concat(a.splice(x + 1).sort())

Приклад:

кроки

Демо


Ви не можете сортувати, а не повертати назад? Також я думаю, що v<a[i+1]&&(t=v,x=i)економить байт, і ви, можливо, зможете більше заощадити, використовуючи spliceзамість двох sliceс.
Ніл

@Neil Хороший улов!
Арнольд

Я думаю, що мені вдалося також об'єднати два maps за 112 байт:a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,t=a.splice(++x).sort(),a.concat(t))
Ніл

Я мушу визнати, що я не думав, a.concat(a.splice(++x).sort())що працюватиму інакше, я б спробував це ...
Ніл

@Neil Дякую! Оновлено. (Ще 4 байт збережені , тому що ми на самому ділі не потрібно т до CONCAT () ).
Арнольд

1

Желе , 6 байт

Œ¿’œ?Ṣ

Цикли через перестановки у низхідному лексикографічному порядку.

Спробуйте в Інтернеті!

Як це працює

Œ¿’œ?Ṣ  Main link. Argument: A (array)

Œ¿      Compute the permutation index n of A, i.e., the index of A in the
        lexicographically sorted list of permutations of A.
  ’     Decrement the index by 1, yielding n-1.
     Ṣ  Sort A.
   œ?   Getthe (n-1)-th permutation of sorted A.

1

C, 161 байт

Фактичний алгоритм O (n).

#define S(x,y){t=x;x=y;y=t;}
P(a,n,i,j,t)int*a;{for(i=n;--i&&a[i-1]>a[i];);for(j=n;i&&a[--j]<=a[i-1];);if(i)S(a[i-1],a[j])for(j=0;j++<n-i>>1;)S(a[i+j-1],a[n-j])}

Приклад використання:

int main(int argc, char** argv) {
    int i;
    int a[] = {1, 2, 3, 4};

    for (i = 0; i < 25; ++i) {
        printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
        P(a, 4);
    }

    return 0;
}

1

Python 2 , 154 байти

x=input()
try:exec'%s=max(k for k in range(%s,len(x))if x[%s-1]<x[k]);'*2%tuple('i1kjii');x[i-1],x[j]=x[j],x[i-1];x[i:]=x[:i-1:-1]
except:x.sort()
print x

Спробуйте в Інтернеті!


Я думаю, що це коротше як функція, яка перетворює список на місці.
orlp

Я спробував це, але execдав мені всілякі помилки у функції
Денніс

0

Желе , 10 байт

ṢŒ!Q©i⁸‘ị®

Спробуйте в Інтернеті!

Сортувати> усі перестановки> знайти вхідні дані> додати 1> індекс у "всю перестановку


@PeterTaylor Я це виправив.
Leaky Nun

Існують специфічні вбудовані перестановки (тобто ви просто можете це зробити Œ¿‘œ?Ṣ). Я не відчував крадіжки з того часу, ну, це ж альго.
Erik the Outgolfer

@EriktheOutgolfer це може бути трохи безладним для входів, що містять дублікати.
Leaky Nun

Хм ... я так думаю, у мене була версія, яка раніше працювала на це, але ти, здається, використовуєш це Q. Ви все одно можете покататися на гольфі ṢŒ!Qµi³‘ị.
Erik the Outgolfer


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.