Enumerare Derangements


17

Dato un numero intero positivo n genera tutti gli squilibri di n oggetti.

Dettagli

  • Uno squilibrio è una permutazione senza punto fisso. (Questo significa in ogni numero sconvolgimento i non possono essere i ingresso -esimo).
  • L'output dovrebbe consistere in squilibri dei numeri (1,2,,n) (o in alternativa (0,1,2,,n1) ).
  • In alternativa, puoi sempre stampare le variazioni di (n,n1,,1) (o (n1,n2,,1,0) rispettivamente) ma devi specificarlo.
  • L'output deve essere deterministico, cioè ogni volta che viene chiamato il programma con un dato n come input, l'output dovrebbe essere lo stesso (il che include che l'ordine degli squilibri deve rimanere lo stesso) e l'output completo deve essere eseguito all'interno un tempo limitato ogni volta (non è sufficiente farlo con probabilità 1).
  • n2
  • Per alcuni dati puoi generare tutti gli squilibri o in alternativa puoi prendere un altro numero intero che funge da indice e stampare il -esimo squilibrio (nell'ordine che hai scelto).nkk

Esempi

Si noti che l'ordine delle variazioni non deve essere lo stesso elencato qui:

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 conta il numero di squilibri.


Possiamo inviare un generatore?
Fatalizza il

@Fatalize Sì, penso che questo sarebbe abbastanza simile agli altri due metodi citati (o pensi che ci sia un forte argomento contro di esso?).
flawr

1
@Fatalize In realtà sembra che sia possibile restituire un generatore invece di un elenco per impostazione predefinita.
flawr

Risposte:


7

Gelatina , 6 byte

Œ!=ÐṂR

Un collegamento monadico che accetta un numero intero positivo che produce un elenco di elenchi di numeri interi.

Provalo online!

Come?

Œ!=ÐṂ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

Brachylog , 9 byte

⟦kpiᶠ≠ᵐhᵐ

Provalo online!

Questo è un generatore che genera uno squilibrio di [0, …, n-1]daton .

Se lo avvolgiamo in a ᶠ - findall metapredicato, otteniamo tutte le possibili generazioni di disordini dal generatore.

Spiegazione

⟦           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 byte

Una funzione ricorsiva che stampa tutti gli squilibri basati su 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)

Provalo online!

Commentate

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

05AB1E , 9 byte

Lœʒāø€Ë_P

Provalo online!

Spiegazione

L           # push [1 ... input]
 œ          # get all permutations of that list
  ʒ         # filter, keep only lists that satisfy
   āø       # elements zipped with their 1-based index
     €Ë_P   # are all not equal


2

Japt , 8 byte

0-based

o á fÈe¦

Provalo (Il piè di pagina incrementa tutti gli elementi per un confronto più semplice con i casi di test)

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 byte

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

Provalo online!

Indicizzazione basata su 0, elenco di tuple.

itertoolsSoluzione non basata:

Python 2 , 107 byte

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

Provalo online!

Indicizzazione basata su 0, righe di elenchi, programma completo.

Nota: questa soluzione, anche se non importa la itertoolslibreria, non è molto più lunga dell'altra che la importa, perché la maggior parte del grosso qui sta costruendo le permutazioni. Il controllo di derangement è in realtà circa 7 byte aggiuntivi! Il motivo è che il controllo viene eseguito al volo come parte dell'edificio di ogni permutazione. Questo non è vero per l'altra soluzione, in cui è necessario verificare se ogni permutazione restituita dalla itertools.permutationsfunzione è in realtà un disordine e, naturalmente, la mappatura stessa richiede molti byte.


2

MATL , 11 byte

:tY@tb-!AY)

Questo genera tutti gli squilibri in ordine lessicografico.

Provalo online!

Spiegazione con esempio

Considera l'input 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]

2

Perl 5 -MList::Util=none -n , 100 89 byte

$"=',';@b=1..$_;map{%k=$q=0;say if none{++$q==$_||$k{$_}++}/\d+/g}glob join$",("{@b}")x@b

Provalo online!



1

Gaia , 10 byte

┅f⟨:ċ=†ỵ⟩⁇

Provalo online!

┅		| push [1 2 ... n]
 f		| push permutations
  ⟨	⟩⁇	| filter where result of following is truthy
   :ċ		| dup, push [1 2 ... n]
     =†ỵ	| there is no fixed point

1

J , 26 byte

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

Provalo online!

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 byte

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

Provalo online!

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

R + gtools , 62 byte

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

Provalo online!

Molto più efficiente, restituisce un punto in matrixcui ogni riga è un disordine.



1

C ++ (gcc) , 207 196 byte

-5 byte per ceilingcat -6 byte di Roman Odaisky

#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;}

Provalo online!


Puoi fare molto meglio se usi un parametro di output, in particolare se è un array std :: quindi è pre-dimensionato - 145 byte
Roman Odaisky

@RomanOdaisky: bella idea, ma come comprendo le regole del codice golf, dovrai prendere il codice di preallocazione nel conteggio dei byte.
movatica,

@movatica Un'area grigia, penso che il codice sia più probabilmente valido che non valido. Scriverà felicemente i risultati corretti da qualche parte, ed è responsabilità del chiamante leggere l'output. Si noti che algoritmi STL come std::copyaffidano allo stesso modo al chiamante di fornire uno spazio adeguato per l'output.
Roman Odaisky,

@RomanOdaisky: il comportamento STL è davvero un argomento valido.
movatica,

0

C ++ (gcc) , 133 byte

Penso che questo sia diventato abbastanza diverso dall'altra presentazione da meritare una risposta separata. Finalmente un uso per index[array]la sintassi dentro e fuori!

#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;);}

Provalo online!


0

Haskell, 76 byte

n&x=[x++[i]|i<-[1..n],notElem i x,i/=length x+1]
d n=iterate(>>=(n&))[[]]!!n

0

Python 2 , 82 byte

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)]

Provalo online!

88 byte come programma:

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

Provalo online!

93 byte usando itertools:

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

Provalo online!


0

Perl 6 , 49 37 byte

Modifica: dopo alcuni avanti e indietro con Phil H, lo abbiamo ridotto a soli 37 byte:

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

Provalo online!

Usando Whateverall'inizio, possiamo evitare le parentesi (salva 2 caratteri). Quindi usa un Zmetaoperatore con -cui prende ogni elemento di una permutazione (es. 2,3,1) e sottrae 0,1,2 in ordine. Se uno di essi è 0 (falsa), allora tutto il nodo fallisce.


La soluzione originale era ( provalo online! )

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

1
Buon inizio, puoi accorciare il filtro con Z acceso! = Per -7 byte: tio.run/##K0gtyjH7n1upoJamYKvwv7ogtSi3tCSxJDM/…
Phil H

@PhilH Sapevo che doveva esserci un modo per integrare l'operatore zip ma non sono riuscito a capirlo. Nice
user0721090601

PhilH usando questa strategia, può ancora battere altri 3 uccidendo le parentesi: tio.run/##K0gtyjH7n1upoJamYKvwv7ogtSi3tCSxJDM/…
user0721090601

PhilH, l'ultimo non funziona. Per tutti tranne n = 2 più di un solo elemento verrà rifiutato
user0721090601

Certo, ho dimenticato il requisito ... rimosso
Phil H,

0

Carbone , 44 28 byte

barrato 44 è ancora regolare 44

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Liberamente basato sulla risposta non itertools di @ EricTheOutgolfer. Spiegazione:

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 byte

f*F.e-bkT.PU

Provalo online!

           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

Il filtro funziona in questo modo: se un elemento si trova nella sua posizione originale, (elemento-indice) sarà 0 e l'intero prodotto sarà 0, e quindi falso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.