Imprima as permutações “pares” do grupo simétrico Sn em notação cíclica


9

A TAREFA

DEFINIÇÕES

Considere os pontos {1,2,3,4,5} e todas as suas permutações. Podemos encontrar o número total de permutações possíveis desses 5 pontos com um truque simples: Criação de imagens preenchendo 5 slots com esses pontos, o primeiro slot terá 5 números possíveis, o segundo 4 (como um foi usado para preencher o primeiro slot) o terceiro 3 e assim por diante. Assim, o número total de permutações é 5 * 4 * 3 * 2 * 1; isso seria 5! permutações ou 120 permutações. Podemos pensar nisso como o grupo simétrico S5, e então o grupo simétrico Sn teria n! or (n*n-1*n-2...*1)permutações.

Uma permutação "par" é aquela em que existe um número par de ciclos de comprimento par. É mais fácil de compreender quando escrito em notação cíclico, por exemplo, (1 2 3)(4 5)permuta-se 1->2->3->1e 4->5->4e tem um ciclo de 3 comprimento (1 2 3)e um ciclo de 2 comprimento (4 5). Ao classificar uma permutação como ímpar ou par, ignoramos os ciclos de comprimento ímpares e dizemos que essa permutação [ (1 2 3)(4 5)] é ímpar, pois possui um número ímpar {1} de ciclos de comprimento par. Mesmo exemplos:

  1. (1)(2 3)(4 5)= dois ciclos de 2 comprimentos | MESMO |
  2. (1 2 3 4 5)= sem ciclos de comprimento uniforme | MESMO | * observe que, se não houver ciclos de comprimento iguais, a permutação será uniforme.

Exemplos ímpares:

  1. (1 2)(3 4 5)= um ciclo de 2 comprimentos | ODD
  2. (1)(2 3 4 5)= um ciclo de 4 comprimentos | ODD

Como exatamente metade das permutações em qualquer grupo simétrico são iguais, podemos chamar o grupo par de Grupo Alternativo N, assim como S5 = 120 A5 = 60 permutações.

NOTAÇÃO

As permutações devem, pelo menos para isso, ser escritas em notação cíclica, onde cada ciclo está entre parênteses diferentes e cada ciclo segue em ordem crescente. Por exemplo, (1 2 3 4 5)não (3 4 5 1 2). E para ciclos com um único número, como: (1)(2 3 4)(5)os pontos únicos / fixos podem ser excluídos (1)(2 3 4)(5) = (2 3 4). Mas a identidade {o ponto em que todos os pontos são fixos (1)(2)(3)(4)(5)} deve ser escrita como ()apenas para representá-la.

O DESAFIO

Gostaria que você, no menor código possível, pegue qualquer número inteiro positivo como entrada {1,2,3,4 ...} e exiba todas as permutações do Grupo Alternativo An onde n é a entrada / todos os pares permutações de Sn. Por exemplo:

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, como nos exemplos, eu gostaria que todos os ciclos de um comprimento fossem eliminados, e quanto à identidade: saídas de nada, (){não apenas entre parênteses, mas com o que você estiver usando para mostrar permutações diferentes} ou idseja aceitável.

LEITURA EXTRA

Você pode encontrar mais informações aqui:

BOA SORTE

E como esse é o codegolf, quem pode imprimir as permutações do Alternating Group An nos bytes mais curtos ganha.


2
Bem-vindo à Programação de Puzzles e Code Golf! Normalmente, permitimos que a saída seja flexível, para que os idiomas que tenham problemas com a saída no formato certo não tenham uma desvantagem injusta. É permitido produzir, por exemplo, em [[1, 2], [3, 4]]vez de (1 2)(3 4)?
— Adnan

@ Adnan Sim, eu deveria ter esclarecido. Desde que os diferentes ciclos sejam mostrados separadamente, não deve haver problema com a forma como você representou isso.
— Harry

"Uma permutação" par "é aquela em que existe um número par de permutações pares". Parece uma definição cíclica. Talvez introduza a notação do ciclo primeiro e depois reescreva a frase para "... número par de ciclos de comprimento par"?
— Martin Ender

Além disso, como faço para colocar o ciclo (2 3 1 4)em ordem crescente? Você quer dizer que devemos colocar o menor elemento na frente?
— Martin Ender

@MartinEnder Sim o menor elemento deve ir primeiro, desde que ele não mexer com a ordem, de modo (2 3 1 4)que 2->3->1->4->2ele pode ser escrito (1 4 2 3)com o seu elemento mais pequeno primeiro
— Harry

Respostas:


5

Pitão, 26 bytes

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.

Experimente online

Esta solução é baseada em uma bijeção pura entre permutações na notação de uma linha e permutações na notação de ciclo. Obviamente, existe a bijeção óbvia em que as duas notações representam a mesma permutação:

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

mas isso exigiria muito código. Em vez disso, basta cortar a notação de uma linha em pedaços antes de todos os números menores que todos os seus predecessores, chamar esses ciclos de pedaços e criar uma nova permutação a partir deles.

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

Para reverter essa bijeção, podemos fazer qualquer permutação na forma de ciclo, girar cada ciclo para que seu menor número seja o primeiro, classificar os ciclos para que seus menores números apareçam em ordem decrescente e apagar todos os parênteses.


O PO exige que a permutação de identidade seja representada sem um ciclo. Eu acho que seria melhor se não fosse o caso.
— milhas

11
Harry pareceu concordar com a minha resposta Jelly, que imprime 1 ciclo mesmo id. Talvez ele pudesse entrar?
— Lynn

Não tenho tanta certeza também da maneira como está redigida e não percebi que a sua solução (de Lynn) também fazia o mesmo.
— milhas

Meu entendimento era que você não podia representar a permutação de identidade usando a string vazia, então alterei minha resposta para manter todos os ciclos de 1 (economizando convenientemente 6 bytes).
— Neil

11
Editei minha pergunta para ficar mais clara. Gostaria que os "um ciclo" fossem eliminados, como você fez na segunda parte de sua resposta. Bem feito pelo caminho.
— Harry

6

Mathematica, 84 49 31 bytes

GroupElements@*AlternatingGroup

Composição de duas funções. Saídas no formulário {Cycles[{}], Cycles[{{a, b}}], Cycles[{{c, d}, {e, f}}], ...}representando (), (a b), (c d)(e f), ....


3

J , 53 bytes

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

Os ciclos em cada permutação são representados como matrizes in a box, pois J irá zerar as matrizes irregulares.

Se a saída estiver relaxada, use 41 bytes

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

onde cada permutação pode conter um ciclo 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││
││└─────┘│└─────┘│└───┴───┘│└─────┘│└─────┘│└─────┘│└─────┘│└───┴───┘│└─────┘│└─────┘│└───┴───┘│
└┴───────┴───────┴─────────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┴─────────┘

Para a implementação alternativa,

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

Isso é realmente bonito ... bem feito.
— 21716 Harry

2

Geléia , 34 28 bytes

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

Experimente aqui .

Explicação

Cada linha em um programa Jelly define uma função; o inferior é " main".

  • A primeira linha define uma função que testa se um produto de ciclo é ímpar.

    L€      Length of each
      ’     Add 1 to each length 
       S    Take the sum
        Ḃ   Modulo 2
    
  • A segunda linha normaliza uma partição de uma permutação de [1…n]em um produto de ciclo da seguinte maneira:

         µ€    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.
    

    Isso se transformará, por exemplo, (4 3)(2 5 1)em (1 2 5)(3 4).

Aqui está o programa principal. Ele recebe um argumento nda linha de 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.

Tentei executá-lo com 5 como entrada e não obtive nenhuma saída. Esse script é apenas para os grupos A3 e A4 ou pode oferecer a qualquer grupo? Eu nunca vi Jelly antes, então qualquer explicação seria útil.
— 21716 Harry

Não, eu apenas coloquei 3 e 4 no desafio, até agora você está ganhando, mas eu realmente quero apenas aprender mais.
— Harry

Jelly, na verdade, tem um built-in para partições, que eu esqueci! Felizmente, um amigo me lembrou. Então agora é mais eficiente (manipula n = 5, yay!) E mais curto.
— Lynn

O OP editou a pergunta para esclarecer que os 1 ciclos devem ser elididos.
— Anders Kaseorg

2

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

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

Infelizmente, 88 bytes são suficientes para gerar o grupo alternativo como uma lista de permutações de a, portanto, isso me custa um adicional de 132 130 124 123 123 bytes para converter a saída no formato desejado:

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)

Consegui reduzir minha versão do ES6 para 222 216 215 bytes:

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

Não me importo se o formato não estiver em notação cíclica perfeita, desde que: cada permutação e seus ciclos sejam mostrados separados (como [1 2 3] [4 5] e <<123> <45>> ambos seriam aceitáveis ) e ciclos de um comprimento são elididos. Talvez isso possa encurtar sua resposta
— Harry

@ Harry, eu nunca mostraria (1,2,3)(4,5)- isso é uma permutação estranha! Atualmente eu mostraria, por exemplo (1,2,3)(4)(5)- não apenas a remoção de ciclos de comprimento um me custa 6 bytes, como também acabo com um resultado vazio para o ciclo de identidade, o que me custaria outros 4 bytes para corrigir.
— Neil

Se você quer dizer que nada é impresso para a identidade, eu aceitarei isso como eu disse as for the identity outputs of nothing ... are accepatble. E também o que seria mostrado se você exibir seus "dados brutos", eles vêm na forma (1,2,3) (4) (5) ou como algo mais?
— 21716 Harry

Agora, excluindo os ciclos de comprimento um, incluindo uma entrada em branco para a identidade, e ainda conseguindo salvar um byte!
— Neil

Os dados @Harry Raw seriam [1, 2, 0, 3, 4]para esse exemplo em particular, tão longe do que você deseja.
— Neil

1

GAP , 32 bytes

Obrigado a @ChristianSievers por reduzir a contagem ao meio.

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

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

Formatação muito boa, acho que o GAP foi uma ótima opção para responder a esse problema.
— 21716 Harry

Sua resposta não mostra onde uma permutação termina e a próxima começa. Assumindo que a função não precisa imprimir os valores como um efeito colateral, mas pode apenas retornar os valores como uma lista a ser impressa pelo intérprete, eu fariaf:=n->List(AlternatingGroup(n));
— Christian Sievers
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.