Stampa le permutazioni "pari" del gruppo simmetrico Sn in notazione ciclica


9

L'OBIETTIVO

DEFINIZIONI

Considera i punti {1,2,3,4,5} e tutte le loro permutazioni. Possiamo trovare il numero totale di possibili permutazioni di questi 5 punti con un semplice trucco: Imaging riempire 5 slot con questi punti, il primo slot avrà 5 possibili numeri, il secondo 4 (poiché uno è stato usato per riempire il primo slot) il terzo 3 e così via. Quindi il numero totale di permutazioni è 5 * 4 * 3 * 2 * 1; questo sarebbe 5! permutazioni o 120 permutazioni. Possiamo pensare a questo come al gruppo simmetrico S5 e quindi il gruppo simmetrico Sn avrebbe n! or (n*n-1*n-2...*1)permutazioni.

Una permutazione "pari" è quella in cui esiste un numero pari di cicli di lunghezza pari. È facile capire quando scritto in notazione ciclico, ad esempio (1 2 3)(4 5)permuta 1->2->3->1e 4->5->4ed ha un ciclo 3 lunghezza (1 2 3)ed un ciclo 2 lunghezza (4 5). Quando classifichiamo una permutazione come dispari o addirittura ignoriamo i cicli di lunghezza dispari e diciamo che questa permutazione [ (1 2 3)(4 5)] è dispari in quanto ha un numero dispari {1} di cicli di lunghezza pari. Anche esempi:

  1. (1)(2 3)(4 5)= due cicli di 2 lunghezze ANCHE |
  2. (1 2 3 4 5)= nessun ciclo di lunghezza pari | ANCHE | * notare che se non sono presenti cicli di lunghezza pari, la permutazione è pari.

Esempi dispari:

  1. (1 2)(3 4 5)= un ciclo di 2 lunghezze ODD |
  2. (1)(2 3 4 5)= un ciclo di 4 lunghezze ODD |

Poiché esattamente la metà delle permutazioni in qualsiasi gruppo simmetrico è pari, possiamo anche chiamare il gruppo pari il gruppo alternato N, così come S5 = 120 A5 = 60 permutazioni.

NOTAZIONE

Le permutazioni dovrebbero, almeno per questo, essere scritte in notazione ciclica in cui ogni ciclo è tra parentesi diverse e ogni ciclo va in ordine crescente. Per esempio (1 2 3 4 5)no (3 4 5 1 2). E per cicli con un singolo numero, come ad esempio: (1)(2 3 4)(5)i punti singoli / fissi possono essere esclusi significato (1)(2 3 4)(5) = (2 3 4). Ma l'identità {il punto in cui sono fissati tutti i punti (1)(2)(3)(4)(5)} dovrebbe essere scritta ()solo per rappresentarla.

LA SFIDA

Vorrei che tu, nel minor numero possibile di codice, prendessi qualsiasi numero intero positivo come input {1,2,3,4 ...} e visualizzi tutte le permutazioni del gruppo alternato An dove n è l'input / tutto il pari permutazioni di Sn. Per esempio:

Input = 3
()
(1 2 3)
(1 3 2)

e

Input = 4
()
(1 2)(3 4)
(1 3)(2 4)
(1 4)(2 3)
(1 2 3)
(1 3 2)
(1 2 4)
(1 4 2)
(1 3 4)
(1 4 3)
(2 3 4)
(2 4 3)

E come negli esempi, vorrei che tutti i cicli di una lunghezza fossero elisi, e per quanto riguarda l'identità: output di nulla, (){non solo parentesi ma con qualunque cosa tu stia usando per mostrare permutazioni diverse} o idsiano accettabili.

LETTURA EXTRA

Puoi trovare maggiori informazioni qui:

IN BOCCA AL LUPO

E poiché questo è codegolf, chiunque può stampare le permutazioni del gruppo alternato An nei byte più corti vince.


2
Benvenuti in Puzzle di programmazione e Code Golf! Normalmente, consentiamo che l'output sia flessibile, in modo che le lingue che hanno problemi con l'output nel formato giusto non abbiano uno svantaggio ingiusto. È consentito l'output ad esempio [[1, 2], [3, 4]]anziché (1 2)(3 4)?
Adnan,

@Adnan Sì, avrei dovuto chiarire. Finché i diversi cicli sono mostrati separatamente, non dovrebbe esserci alcun problema con il modo in cui lo hai rappresentato.
Harry

"Una permutazione" pari "è quella in cui esiste un numero pari di permutazioni pari". Sembra una definizione ciclica. Forse prima introdurre la notazione del ciclo e poi riscrivere quella frase in "... numero pari di cicli di lunghezza pari"?
Martin Ender,

Inoltre, come posso mettere il ciclo (2 3 1 4)in ordine crescente? Vuoi dire che dovremmo solo mettere l'elemento più piccolo in primo piano?
Martin Ender,

@MartinEnder Sì l'elemento più piccolo deve andare in primo luogo finché non lo fa confusione con l'ordine, in modo da (2 3 1 4)non 2->3->1->4->2può essere scritto (1 4 2 3)con il suo elemento più piccolo prima
Harry

Risposte:


5

Pyth, 26 byte

t#Mf%+QlT2mcdf<>dTS<dTd.pS

          m            .pSQ   Map over permutations d of [1, …, Q]:
             f        d         Find all indices T in [1, …, Q] such that
               >dT                the last Q-T elements of d
              <   S<dT            is less than the sorted first T elements of d
           cd                   Chop d at those indices
   f                          Filter on results T such that
      Q                         the input number Q
     + lT                       plus the length of T
    %    2                      modulo 2
                                is truthy (1)
t#M                           In each result, remove 0- and 1-cycles.

Provalo online

Questa soluzione si basa su una biiezione ordinata tra permutazioni nella notazione a riga singola e permutazioni nella notazione ciclica. Naturalmente, c'è l'ovvia biiezione in cui le due notazioni rappresentano la stessa permutazione:

[8, 4, 6, 3, 10, 1, 5, 9, 2, 7] = (1 8 9 2 4 3 6) (5 10 7)

ma questo richiederebbe troppo codice. Invece, basta tagliare la notazione di una riga in pezzi prima di tutti i numeri che sono più piccoli di tutti i loro predecessori, chiamare questi cicli di pezzi e costruirne una nuova permutazione.

[8, 4, 6, 3, 10, 1, 5, 9, 2, 7] ↦ (8) (4 6) (3 10) (1 5 9 2 7)

Per invertire questa biiezione, possiamo prendere qualsiasi permutazione in forma di ciclo, ruotare ogni ciclo in modo che il primo sia il suo numero più piccolo, ordinare i cicli in modo che i loro numeri più piccoli appaiano in ordine decrescente e cancellare tutte le parentesi.


L'OP richiede che la permutazione dell'identità sia rappresentata senza un ciclo. Penso che sarebbe meglio se non fosse così.
miglia

1
Harry sembrava a posto la mia risposta di Jelly, che stampa 1 cicli anche per id. Forse potrebbe entrare?
Lynn,

Non sono così sicuro del modo in cui è scritto, e non ho notato che anche la tua soluzione (di Lynn) ha fatto lo stesso.
miglia

La mia comprensione era che non si poteva rappresentare la permutazione dell'identità usando la stringa vuota, quindi ho modificato la mia risposta per mantenere tutti i 1 cicli (anche salvando convenientemente 6 byte).
Neil,

1
Ho modificato la mia domanda in modo che sia più chiaro, vorrei che i "cicli uno" fossero elisi come hai fatto nella seconda parte della tua risposta. Ben fatto comunque.
Harry

6

Mathematica, 84 49 31 byte

GroupElements@*AlternatingGroup

Composizione di due funzioni. Output nella forma che {Cycles[{}], Cycles[{{a, b}}], Cycles[{{c, d}, {e, f}}], ...}rappresenta (), (a b), (c d)(e f), ....


3

J , 53 byte

[:(<@((>:@|.~]i.<./)&.>@#~1<#@>)@C.@#~1=C.!.2)!A.&i.]

I cicli in ciascuna permutazione sono rappresentati come array inscatolati poiché J non impacchetterà gli array irregolari.

Se l'output è rilassato, utilizzare 41 byte

[:((1+]|.~]i.<./)&.>@C.@#~1=C.!.2)!A.&i.]

dove ogni permutazione può contenere cicli uno e zero.

uso

   f =: [:(<@((>:@|.~]i.<./)&.>@#~1<#@>)@C.@#~1=C.!.2)!A.&i.]
   f 3
┌┬───────┬───────┐
││┌─────┐│┌─────┐│
│││1 2 3│││1 3 2││
││└─────┘│└─────┘│
└┴───────┴───────┘
   f 4
┌┬───────┬───────┬─────────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┬─────────┐
││┌─────┐│┌─────┐│┌───┬───┐│┌─────┐│┌─────┐│┌─────┐│┌─────┐│┌───┬───┐│┌─────┐│┌─────┐│┌───┬───┐│
│││2 3 4│││2 4 3│││1 2│3 4│││1 2 3│││1 2 4│││1 3 2│││1 3 4│││1 3│2 4│││1 4 2│││1 4 3│││2 3│1 4││
││└─────┘│└─────┘│└───┴───┘│└─────┘│└─────┘│└─────┘│└─────┘│└───┴───┘│└─────┘│└─────┘│└───┴───┘│
└┴───────┴───────┴─────────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┴─────────┘

Per l'implementazione alternativa,

   f =: [:((1+]|.~]i.<./)&.>@C.@#~1=C.!.2)!A.&i.]
   f 3
┌─────┬─┬─┐
│1    │2│3│
├─────┼─┼─┤
│1 2 3│ │ │
├─────┼─┼─┤
│1 3 2│ │ │
└─────┴─┴─┘

In realtà è bellissimo ... ben fatto.
Harry

2

Gelatina , 34 28 byte

L€’SḂ
ṙLR$Ṃµ€Ṣ
Œ!ŒṖ€;/Ç€ÑÐḟQ

Provalo qui .

Spiegazione

Ogni riga in un programma Jelly definisce una funzione; quello in basso è “ main”.

  • La prima riga definisce una funzione che verifica se un prodotto del ciclo è dispari.

    L€      Length of each
      ’     Add 1 to each length 
       S    Take the sum
        Ḃ   Modulo 2
    
  • La seconda riga normalizza una partizione di una permutazione [1…n]in un prodotto del ciclo come segue:

         µ€    For each list X in the partition:
    ṙLR$          Rotate X by each element in [1…length(X)].
        Ṃ         Get the lexicographically smallest element.
                  Thus, find the rotation so that the smallest element is in front.
           Ṣ   Sort the cycles in the partition.
    

    Questo si trasformerà ad esempio (4 3)(2 5 1)in (1 2 5)(3 4).

Ecco il programma principale. Prende un argomento ndalla riga di comando e:

Œ!              Compute all permutations of [1…n].
  ŒṖ€           Compute all partitions of each permutation.
     ;/         Put them in one big list.
       ǀ       Normalize each of them into a cycle product.
         ÑÐḟ    Reject elements satisfying the top function,
                i.e. keep only even cycle products.
            Q   Remove duplicates.

Ho provato a eseguirlo con 5 come input e non ho ottenuto alcun output. Questo script è solo per i gruppi A3 e A4 o può potenzialmente dare qualsiasi gruppo? Non ho mai visto Jelly prima d'ora, quindi qualsiasi spiegazione sarebbe utile.
Harry

No, ho solo messo 3 e 4 nella sfida, quindi finora stai vincendo, ma voglio solo saperne di più.
Harry

Jelly in realtà ha un built-in per le partizioni, che mi sono dimenticato! Per fortuna, un amico mi ha ricordato. Quindi ora è più efficiente (gestisce n = 5, yay!) E più breve.
Lynn,

OP ha modificato la domanda per chiarire che devono essere elusi 1 cicli.
Anders Kaseorg,

2

JavaScript (Firefox 30-57), 220 218 212 211 byte

f=(a,p)=>a[2]?[for(i of a)for(j of f(a.filter(m=>m!=i),p,p^=1))[i,...j]]:[[a[p],a[p^1]]]

Purtroppo 88 byte sono sufficienti per generare il gruppo alternato come un elenco di permutazioni di a, quindi mi costa un ulteriore 132 130 124 123 byte per convertire l'output nel formato desiderato:

n=>f([...Array(n).keys()],0).map(a=>a.map((e,i)=>{if(e>i){for(s+='('+-~i;e>i;[a[e],e]=[,a[e]])s+=','+-~e;s+=')'}},s='')&&s)

Sono riuscito a tagliare la mia versione ES6 fino a 222 216 215 byte:

n=>(g=(a,p,t=[])=>a[2]?a.map(e=>g(a.filter(m=>m!=e),p,[...t,e],p^=1)):[...t,a[p],a[p^1]].map((e,i,a)=>{if(e>i){for(s+='('+-~i;e>i;[a[e],e]=[,a[e]])s+=','+-~e;s+=')'}},s='')&&r.push(s))([...Array(n).keys(r=[])],0)&&r

Non mi importa se il formato non è in perfetta notazione ciclica fintanto che: ogni permutazione e i suoi cicli sono mostrati separati (come [1 2 3] [4 5] e <<123> <45>> sarebbero entrambi accettabili ) e vengono eliminati cicli di una lunghezza. Forse questo può abbreviare la tua risposta
Harry

@Harry non lo mostrerei mai (1,2,3)(4,5)- è una strana permutazione! Attualmente mostrerei ad esempio (1,2,3)(4)(5): non solo la rimozione di cicli di lunghezza uno mi costa 6 byte, ma alla fine con un risultato vuoto per il ciclo di identità che mi costerebbe altri 4 byte da correggere.
Neil,

Se intendi che non viene stampato nulla per l'identità, accetterò quello che ho detto as for the identity outputs of nothing ... are accepatble. E anche cosa verrebbe mostrato se si generano i "dati non elaborati", nel formato (1,2,3) (4) (5) o come altro?
Harry

@Harry Ora escludendo i cicli di lunghezza uno, inclusa una voce vuota per l'identità, e riuscendo comunque a salvare un byte!
Neil,

I dati di @Harry Raw sarebbero [1, 2, 0, 3, 4]per quel particolare esempio, quindi da nessuna parte vicino a quello che vuoi.
Neil,

1

GAP , 32 byte

Grazie a @ChristianSievers per aver dimezzato il conteggio.

f:=n->List(AlternatingGroup(n));

Utilizzo al prompt:

gap> f(4);
[ (), (1,3,2), (1,2,3), (1,4,3), (2,4,3), (1,3)(2,4), (1,2,4), (1,4)(2,3), (2,3,4), (1,3,4), (1,2)(3,4), (1,4,2) ]

Ottima formattazione, penso che GAP sia stata un'ottima scelta per rispondere a questo problema.
Harry

La tua risposta non mostra dove finisce una permutazione e inizia la successiva. Supponendo che la funzione non debba stampare i valori come effetto collaterale, ma potrebbe semplicemente restituire i valori come un elenco da stampare dall'interprete, lo fareif:=n->List(AlternatingGroup(n));
Christian Sievers,
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.