Перерахуйте дерантації


17

З огляду на деяке додатне ціле число генерують усі дерангування об’єктів.nn

Деталі

  • Дезорганізація - перестановка без фіксованої точки. (Це означає, що в кожному номері дерангування i не можу бути в i -му записі).
  • Вихід повинен складатися з деригацій чисел (1,2,,n) (або альтернативно (0,1,2,,n1) ).
  • Ви також можете завжди друкувати дерангування (n,n1,,1) (або (n1,n2,,1,0) відповідно), але це потрібно вказати.
  • Вихід повинен бути детермінованим, тобто, коли програма викликається з деяким заданим n як вхід, вихід повинен бути однаковим (що включає, що порядок дерангувань повинен залишатися однаковим), а повний вихід повинен бути виконаний у межах щомісяця обмежений час (недостатньо це робити з імовірністю 1).
  • Можна припустити, що n2
  • Для деяких заданих n ви можете або генерувати всі відміни, або ви можете взяти інше ціле число k яке служить в якості індексу, і надрукувати k -му відмітку (у вибраному вами порядку).

Приклади

Зауважте, що порядок відхилень не повинен бути таким, як зазначено тут:

n=2: (2,1)
n=3: (2,3,1),(3,1,2)
n=4: (2,1,4,3),(2,3,4,1),(2,4,1,3), (3,1,4,2),(3,4,1,2),(3,4,2,1), (4,1,2,3),(4,3,1,2),(4,3,2,1)

OEIS A000166 підраховує кількість відхилень .


Чи можемо ми подати генератор?
Фаталізувати

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

1
@Fatalize Насправді, здається, повернення генератора замість списку можливе за замовчуванням.
flawr

Відповіді:


7

Желе , 6 байт

Œ!=ÐṂR

Монадична посилання, що приймає додатне ціле число, яке дає список списків цілих чисел.

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

Як?

Œ!=ÐṂR - Link: integer, n
Œ!     - all permutations of (implicit range of [1..n])
     R - range of [1..n]
   ÐṂ  - filter keep those which are minimal by:
  =    -   equals? (vectorises)
       -   ... i.e. keep only those permutations that evaluate as [0,0,0,...,0]

5

Брахілог , 9 байт

⟦kpiᶠ≠ᵐhᵐ

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

Це генератор, який виводить одну деградацію [0, …, n-1]заданого n.

Якщо ми загорнемо його в ᶠ - findallметапредмет, ми отримаємо генератор усіх можливих поколінь порушень.

Пояснення

⟦           The range [0, …, Input]
 k          Remove the last element
  p         Take a permutation of the range [0, …, Input - 1]
   iᶠ       Take all pair of Element-index: [[Elem0, 0],…,[ElemN-1, N-1]]
     ≠ᵐ     Each pair must contain different values
       hᵐ   The output is the head of each pair

5

JavaScript (V8) , 85 байт

Рекурсивна функція, що друкує всі 0-базі.

f=(n,p=[],i,k=n)=>k--?f(n,p,i,k,k^i&&!p.includes(k)&&f(n,[...p,k],-~i)):i^n||print(p)

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

Прокоментував

f = (                   // f is a recursive function taking:
  n,                    //   n   = input
  p = [],               //   p[] = current permutation
  i,                    //   i   = current position in the permutation
  k = n                 //   k   = next value to try
) =>                    //         (a decrementing counter initialized to n)
  k-- ?                 // decrement k; if it was not equal to 0:
    f(                  //   do a recursive call:
      n, p, i, k,       //     leave all parameters unchanged
      k ^ i &&          //     if k is not equal to the position
      !p.includes(k) && //     and k does not yet appear in p[]:
        f(              //       do another recursive call:
          n,            //         leave n unchanged
          [...p, k],    //         append k to p
          -~i           //         increment i
                        //         implicitly restart with k = n
        )               //       end of inner recursive call
    )                   //   end of outer recursive call
  :                     // else:
    i ^ n ||            //   if the derangement is complete:
      print(p)          //     print it




2

Japt , 8 байт

На основі 0

o á fÈe¦

Спробуйте (збільшуючи колонтитули всіх елементів для легшого порівняння з тестовими кейсами)

o á fÈe¦     :Implicit input of integer
o            :Range [0,input)
  á          :Permutations
    f        :Filter
     È       :By passing each through this function
      e      :  Every element of the permutation
       ¦     :  Does not equal its 0-based index

2

Python 2 , 102 байти

lambda n:[p for p in permutations(range(n))if all(i-j for i,j in enumerate(p))]
from itertools import*

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

Індексація на основі 0, список кортежів.

Non- itertoolsзасноване рішення:

Python 2 , 107 байт

n=input()
for i in range(n**n):
 t=[];c=1
 for j in range(n):c*=j!=i%n not in t;t+=[i%n];i/=n
 if c:print t

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

Індексація на основі 0, рядки списків, повна програма.

Примітка. Це рішення, хоча воно не імпортує itertoolsбібліотеку, не набагато довше, ніж інше, яке імпортує його, тому що більша частина тут створює перестановки. Перевірка дезарганізації насправді становить приблизно 7 додаткових байтів! Причина в тому, що перевірка робиться на льоту як частина будівлі кожної перестановки. Це не вірно для іншого рішення, де ви повинні перевірити, чи кожна перестановка, повернута itertools.permutationsфункцією, насправді є дезорганізацією, і, звичайно, саме відображення займає багато байт.


2

MATL , 11 байт

:tY@tb-!AY)

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

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

Пояснення на прикладі

Розглянемо вхід 3.

:     % Implicit input n. Range [1 2 ... n]
      % STACK: [1 2 3]
t     % Duplicate
      % STACK: [1 2 3], [1 2 3]
Y@    % All permutations, in lexicographical order, as rows of a matrix
      % STACK: [1 2 3], [1 2 3; 1 3 2; ··· ; 3 2 1]
t     % Duplicate
      % STACK: [1 2 3], [1 2 3; 1 3 2; ··· ; 3 2 1], [1 2 3; 1 3 2; ··· ; 3 2 1]
b     % Bubble up: moves third-topmost element in stack to the top
      % STACK: [1 2 3; 1 3 2; ··· ; 3 2 1], [1 2 3; 1 3 2; ··· ; 3 1 2; 3 2 1], [1 2 3]
-     % Subtract, element-wise with broadcast
      % STACK: [1 2 3; 1 3 2; ··· ; 3 2 1], [0 0 0; 0 1 -1; ··· ; 2 -1 -1; 2 0 -2]
!A    % True for rows containining only nonzero elements
      % STACK: [1 2 3; 1 3 2; ··· ; 3 1 2; 3 2 1], [false false ··· true false]
Y)    % Use logical mask as a row index. Implicit display
      % STACK: [2 3 1; 3 1 2]




1

J , 26 байт

i.(]#~0~:*/@(-|:))i.@!A.i.

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

i. (] #~ 0 ~: */@(- |:)) i.@! A. i.
i. (                   )            NB. 0..input
   (                   ) i.@! A. i. NB. x A. y returns the
                                    NB. x-th perm of y
                                    NB. i.@! returns 
                                    NB. 0..input!. Combined
                                    NB. it produces all perms
                                    NB. of y
    ] #~ 0 ~: */@(- |:)             NB. those 2 are passed as
                                    NB. left and right args
                                    NB. to this
    ] #~                            NB. filter the right arg ]
                                    NB. (all perms) by:
         0 ~:                       NB. where 0 is not equal to...
              */@                   NB. the product of the 
                                    NB. rows of...
                 (- |:)             NB. the left arg minus
                                    NB. the transpose of
                                    NB. the right arg, which
                                    NB. will only contain 0
                                    NB. for perms that have
                                    NB. a fixed point

1

R , 81 80 байт

function(n)unique(Filter(function(x)all(1:n%in%x&1:n-x),combn(rep(1:n,n),n,,F)))

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

list(н2н)n[1..n]n1:n%in%x1:n-x

R + gtools , 62 байти

function(n,y=gtools::permutations(n,n))y[!colSums(t(y)==1:n),]

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

Набагато ефективніше повертає точку, matrixде кожен рядок - це недоречність.



1

C ++ (gcc) , 207 196 байт

-5 байт по стелі -6 байт Романа Одайського

#include<regex>
#define v std::vector
auto p(int n){v<v<int>>r;v<int>m(n);int i=n;for(;m[i]=--i;);w:for(;std::next_permutation(&m[0],&m[n]);r.push_back(m))for(i=n;i--;)if(m[i]==i)goto w;return r;}

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


Ви можете зробити набагато краще, якщо використовуєте вихідний параметр, особливо якщо це std :: масив, тому він має попередній розмір - 145 байт
Roman Odaisky,

@RomanOdaisky: приємна ідея, але, як я розумію правила кодового гольфу, вам доведеться взяти код попереднього розміщення у свій байт.
movatica

@movatica Сіра зона, я думаю, що код швидше дійсний, ніж недійсний. Він із задоволенням запише правильні результати десь, і відповідальність за те, щоб абонент читав висновок. Зауважте, що алгоритми STL, такі як std::copyаналогічно, довіряють абоненту надання належного простору для виводу.
Роман Одайський

@RomanOdaisky: поведінка STL - це дійсно вагомий аргумент.
movatica

0

C ++ (gcc) , 133 байт

Я думаю, що це досить різнилося від інших подань, щоб заслужити окрему відповідь. Нарешті, використання для index[array]синтаксису зсередини!

#include<regex>
[](int n,auto&r){int i=n;for(;i[*r]=--i;);for(;std::next_permutation(*r,*r+n);)for(i=n;i--?(r[1][i]=i[*r])-i:!++r;);}

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



0

Пітон 2 , 82 байти

f=lambda n,i=0:i/n*[[]]or[[x]+l for l in f(n,i+1)for x in range(n)if~-(x in[i]+l)]

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

88 байт як програма:

M=[],
r=range(input())
for i in r:M=[l+[x]for l in M for x in r if~-(x in[i]+l)]
print M

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

93 байти за допомогою itertools:

from itertools import*
r=range(input())
print[p for p in permutations(r)if all(map(cmp,p,r))]

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


0

Perl 6 , 49 37 байт

Редагувати: Після декількох перемог з Філом Н ми звели його лише до 37 байт:

(^*).permutations.grep:{all @_ Z-^@_}

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

Використовуючи Whateverна початку, ми можемо уникнути дужок (економить 2 символи). Далі використовуйте Zметаоператор, за допомогою -якого беруть кожен елемент перестановки (наприклад, 2,3,1) і віднімають 0,1,2 по порядку. Якщо будь-який з них дорівнює 0 (фальшивий), то всі з'єднання провалюються.


Оригінальним рішенням було ( Спробуйте в Інтернеті! )

{permutations($_).grep:{none (for $_ {$++==$_})}}

1
Добрий початок, ви можете зробити фільтр коротшим із Z на! = Для -7 байт: tio.run/##K0gtyjH7n1upoJamYKvwv7ogtSi3tCSxJDM/…
Phil H

@PhilH Я знав, що має бути спосіб інтегрувати zip-оператор, але я не міг це зрозуміти. Ніцца
користувач0721090601

PhilH, використовуючи цю стратегію, все ще може збити ще 3, вбивши круглі дужки: tio.run/##K0gtyjH7n1upoJamYKvwv7ogtSi3tCSxJDM/…
user0721090601

Філ, останній не працює. Для всіх, крім n = 2, більше одного елемента буде відхилено
user0721090601

Звичайно, забув вимогу ... знято
Філ Х

0

Вугілля деревне , 44 28 байт

перекреслений 44 все ще є регулярним 44

NθIΦEXθθEθ﹪÷ιXθλθ⬤ι‹⁼μλ⁼¹№ιλ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Повноцінно ґрунтується на відповіді на не-itertools @ EricTheOutgolfer. Пояснення:

Nθ                              Input `n`
     Xθθ                        `n` raised to power `n`
    E                           Mapped over implicit range
         θ                      `n`
        E                       Mapped over implicit range
            ι                   Outer loop index
           ÷                    Integer divided by
             Xθ                 `n` raised to power
               λ                Inner loop index
          ﹪     θ               Modulo `n`
   Φ                            Filtered where
                  ι             Current base conversion result
                 ⬤              All digits satisfy
                         №ιλ    Count of that digit
                       ⁼¹       Equals literal 1
                   ‹            And not
                    ⁼μλ         Digit equals its position
  I                             Cast to string
                                Implicitly print


0

Pyth , 12 байт

f*F.e-bkT.PU

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

           UQ # [implicit Q=input] range(0,Q)
         .P  Q# [implicit Q=input] all permutations of length Q
f             # filter that on lambda T:
   .e   T     #   enumerated map over T: lambda b (=element), k (=index):
     -bk      #     b-k
 *F           # multiply all together

Фільтр працює так: якщо будь-який елемент знаходиться на своєму початковому місці, (елемент-індекс) буде 0, а весь продукт буде 0, а значить, і фальси.

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