Composizione di permutazioni - il prodotto del gruppo


12

Date due permutazioni in forma di ciclo disgiunto, produrre il loro prodotto / composizione in forma di ciclo disgiunto.

Q · P = (1 5) (2 4) · (1 2 4 3) = (1 4 3 5).

Per trovare la composizione, converti i cicli disgiunti in permutazioni in notazione a due righe. Ogni numero in una parte disgiunta di un ciclo è mappato al numero che lo segue nella stessa parte. Si avvolge. Così 1 -> 5, 5 -> 1, 2 -> 4, 4 -> 2. Se un numero non viene trovato, 3 -> 3viene mappato su se stesso. Il primo ciclo disgiunto potrebbe anche essere scritto (1 5)(2 4)(3). Queste mappature vengono convertite in due righe, in questo modo (si noti che l'ordine di P e Q sono invertiti):

Caspita, questa immagine è enorme!

Il prodotto di due permutazioni si ottiene riorganizzando le colonne della seconda permutazione (più a sinistra) in modo che la sua prima fila sia identica alla seconda riga della prima (più a destra) permutazione. Il prodotto può quindi essere scritto come prima riga della prima permutazione sulla seconda riga della seconda permutazione modificata.

inserisci qui la descrizione dell'immagine

Articolo di Wikipedia


Regole:

  • L'input verrà fornito come un elenco di elenchi o un formato simile
  • Si può non prendere qualcosa di simile (1 5)(2 4), come [5, 4, 3, 2, 1], già in forma due righe (indice di mappatura a valore)
  • Non tutti i numeri devono essere presenti in ciascun gruppo, quindi potresti avere (1 5)·(1 2), risultando (2 5 1).
  • L'output dovrebbe essere in grado di essere utilizzato come input.
  • Non è necessario supportare l'input con un ciclo vuoto (1 5)·(). Quello sarebbe invece dato come (1 5)·(1)o qualcosa di equivalente.
  • Poiché i cicli si concludono, l'ordine non ha importanza finché il risultato è corretto.
  • Puoi iniziare da zero o uno. Non importa, perché i risultati sono gli stessi.
  • I numeri possono essere più grandi di 9.
  • Non è possibile includere lo stesso numero più di una volta nell'output. Quindi [[1],[1]]non è permesso.
  • Si noti che questa operazione non è commutativa ! Ho messo Q prima di P, perché è quello che ha fatto Wikipedia. Puoi scegliere qualsiasi ordine, ma specifica quale se è diverso.
  • Il codice più corto vince
  • Gli incorporati sono consentiti, ma se ne usi uno, mostra una soluzione anche senza usarla.

Esempi:

Non vengono visualizzate tutte le possibilità di output equivalenti

Input
Output

[[1, 5], [2, 4]], [[1, 2, 4, 3]]
[[1, 4, 3, 5]] (or [[4, 3, 5, 1]] or ...)

[[1, 5]], [[1, 2]]
[[2, 5, 1]]

[[10, 2, 3]], [[2]]
[[3, 10, 2]]

[[1]], [[3]]
[[]] (or [[1]] or something equivalent)

[[10,2,3,15],[1,7],[5,6],[14,4,13,11,12]], [[5,6,7,9,14],[2,8,3,10],[1,11]]
[[12, 14, 6, 1], [8, 15, 10, 3, 2], [13, 11, 7, 9, 4]]

(arguments in reverse order from above gives a different answer)
[[5,6,7,9,14],[2,8,3,10],[1,11]], [[10,2,3,15],[1,7],[5,6],[14,4,13,11,12]]
[[9, 14, 4, 13, 1], [10, 8, 3, 15, 2], [7, 11, 12, 5]]

Per me, queste sono permutazioni , non gruppi di permutazione . Un gruppo di permutazione è una raccolta, chiusa nell'ambito di questa operazione di composizione, di un gruppo di permutazioni individuali.
Greg Martin,

@GregMartin Terminologia fissa
mbomb007,

Risposte:


2

J , 7 byte

C.@C.@,

Provalo online!


L'output dovrebbe essere in grado di essere utilizzato come input.
mbomb007,

@ mbomb007 L'output è utilizzabile come input. Ogni elenco di cicli deve essere un array con indice 0 di array inscatolati.
miglia,

O è il comportamento di stampa predefinito di questa J? Voglio solo assicurarmi che la funzione possa essere concatenata.
mbomb007,

@ mbomb007 Sì, questa è solo la rappresentazione visiva di esso. Deve essere 0-indicizzato, ma l'ho elencato come 1-indicizzato e li converto in 0-index prima che vengano memorizzati nelle variabili da passare alla funzione. Quindi, lo riconvertisco da 0-indicizzato a 1-indicizzato prima di emetterlo.
miglia,

3

Mathematica, 15 byte

##⊙Cycles@{}&

Sì Virginia, c'è un built-in .... Mathematica supporta un tipo di dati di permutazione già nella notazione del ciclo disgiunto: questa pura funzione prende come input un numero qualsiasi di argomenti nella forma Cycles[{{1, 5}, {2, 4}}]e genera la permutazione del prodotto, sempre nella Cycles[]forma. Utilizza la convenzione di ordinamento opposta come OP, quindi ad esempio,

##⊙Cycles@{}&[Cycles[{{1, 2, 4, 3}}], Cycles[{{1, 5}, {2, 4}}]]

ritorna Cycles[{{1, 4, 3, 5}}]. Il simbolo che ho usato sopra dovrebbe davvero essere il simbolo Unicode U + F3DE da 3 byte per uso privato per lavorare in Mathematica. Nota che Mathematica ha un builtin chiamato per questa operazione PermutationProduct, ma è più lungo di tre byte.


3

Haskell , 157 148 byte

MODIFICARE:

  • -9 byte: questo potrebbe davvero essere golfato di più. Rimosse le parentesi ridondanti intorno p++q. Ordine argomento scambiato di g. Mi sono sbarazzato di diniziare iteratecon p x, dopo di che takeWhilenon è più legato con fst+ span. Fatto iterateinfix.

Farlo mentre sono in ritardo ... probabilmente posso giocare ancora a golf.

Era più semplice e sembrava essere consentito, quindi l'output include cicli a elemento singolo.

q#p=g(p++q>>=id)$f q.f p
f p a=last$a:[y|c<-p,(x,y)<-zip(0:c)(c++c),x==a]
g(x:l)p|c<-x:fst(span(/=x)$p`iterate`p x)=c:g[x|x<-l,x`notElem`c]p
g[]p=[]

Provalo online!

Come funziona:

  • #è la funzione principale. q#pprende due elenchi di elenchi di numeri e restituisce un elenco simile. I test sembrano avere Q prima di P, quindi ho usato lo stesso ordine.
  • f pconverte la permutazione pdalla forma ciclo disgiunto ad una funzione, dopo che f qe f ppossono essere composti con il solito operatore di composizione ..
    • La comprensione dell'elenco scorre attraverso i cicli c, cercando ae trovando il suo successore. Se la comprensione non trova nulla, aviene appena restituita.
    • zip(0:c)(c++c)è un elenco di coppie di elementi ce dei loro successori. Poiché la domanda ci permette di "iniziare da uno", possiamo usare 0come valore fittizio; è più economico anteporre questo al zipprimo argomento piuttosto che usarlo tailsul secondo.
  • g l pprende un elenco ldi elementi e una funzione di permutazione pe restituisce l'elenco dei cicli che toccano gli elementi.
    • Ecco cil ciclo che contiene il primo elemento xdell'elenco, gli altri elementi di cvengono trovati ripetendo da p xfino a quando non xviene trovato di nuovo. Quando si ricorre per trovare i cicli rimanenti, tutti gli elementi di cvengono prima rimossi con una comprensione dell'elenco.

Grazie per aver notato che l'ordine conta quando si calcola il risultato. Mi ero dimenticato di aggiungere un esempio o un commento al riguardo. Questo è stato corretto.
mbomb007,

1

Python, 220 byte

a,b=eval(input())
p,o=a+b,[]
for i in range(1,1+max(map(max,p))):
 if not any(i in t for t in o):
  u,m=(i,),i
  while 1:
   for t in p[::-1]:
    if m in t:m=t[(t.index(m)+1)%len(t)]
   if m==i:o+=[u];break
   u+=(m,)
o

2
Benvenuti nel sito. Vedo alcuni modi per accorciarlo. Prendi in considerazione la pagina dei suggerimenti per Python .
Ad Hoc Garf Hunter,

0

Python 3.8 , 187 byte

q,p=eval(input())
g=lambda p,i:[*(c[c.index(i)-1]for c in p if i in c),i][0]
h=lambda*c:(x:=g(p,g(q,c[0])))in c and(*c[(m:=c.index(min(c))):],*c[:m])or h(x,*c)
exit({*map(h,sum(p|q,()))})

Provalo online! oppure Controlla tutti i casi di test!

Input : qe pin quell'ordine, ognuno è un insieme di tuple, da STDIN.
Output : la permutazione del prodotto Q·Pcome un insieme di tuple a STDERR.

Spiegazione

La funzione gtrova quale numero si associa al numero inella permutazione p(aka gè la permutazione inversa di p).

g=lambda p,i:        
[                   # creates a list
  *(                # containing the following
    c[c.index(i)-1] #   the number before i in cycle c
    for c in p      #   for all cycles in permutation
    if i in c       #   if i is in that cycle
  )                 #
  ,i                # adds i to the end of that list
                    #   (in case i is not in any cycle)
][0]                # returns the first element of the list

La funzione haccetta un numero e restituisce il ciclo Q·Pche contiene quel numero. Il ciclo restituito sarà una tupla, formattata in modo tale che l'elemento più piccolo si trovi sull'indice 0.

h=lambda*c:                   # input: an incomplete cycle c, as a list
(x:=g(p,g(q,c[0])))           # finds the number x before the first number in c
in c                          # if x is also in c (aka the cycle is complete)
and                           # then returns the following:
(                             #   c as a tuple with min element at index 0
  *c[(m:=c.index(min(c))):],  #   (c, from the min element to the end)
  *c[:m]                      #   (c, from start to the min element)
)
or                            # else (cycle is incomplete) returns the following
h(x,*c)                       #   recursive result when after prepending x to c

Applicando ha tutti i numeri, possiamo ottenere tutti i cicli Q·P. Per evitare cicli duplicati nel nostro risultato, abbiamo semplicemente messo tutti i cicli in un set. Funziona poiché cicli simili restituiti da hverranno formattati sulla stessa tupla (con l'elemento più piccolo all'indice 0).
Dobbiamo solo considerare i numeri che compaiono in Po Q, poiché tutti gli altri numeri mapperanno su se stessi.

exit(              # returns through STDERR
  {                # create a set from the followings
    *map(h,        #   map function h to
      sum(p|q,())  #   all numbers in P or Q
    )
  }
)
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.