Quale gruppo abeliano finito è questo?


12

Descrizione

Scrivi una funzione f(m, G)che accetta come argomenti una mappatura me un insieme / elenco di interi distinti, non negativi G.

mdovrebbe mappare coppie di numeri interi in Gnuovi numeri interi in G. ( G, m) è garantito per formare un gruppo abeliano finito , ma qualsiasi elemento di Gpuò essere l'identità.

C'è un teorema importante che dice:

[Ogni gruppo abeliano finito] è isomorfo a un prodotto diretto di gruppi ciclici di ordine di potere primario.

fdeve restituire un elenco di poteri primi [p1, ... pn]in ordine crescente tale cheG è isomorfo a Z_p1 volte ... volte Z_pn

Esempi

  • f((a, b) → (a+b) mod 4, [0, 1, 2, 3])dovrebbe tornare [4], poiché i parametri descrivono il gruppo Z 4 .

  • f((a, b) → a xor b, [0, 1, 2, 3])dovrebbe tornare [2, 2], poiché i parametri descrivono un gruppo isomorfo su Z 2 × Z 2 .

  • f((a, b) → a, [9])dovrebbe tornare [], poiché i parametri descrivono il gruppo banale; cioè, il prodotto di zero gruppi ciclici.

  • Definire mcome segue:

    (a, b) → (a mod 3 + b mod 3) mod 3
           + ((floor(a / 3) + floor(b / 3)) mod 3) * 3
           + ((floor(a / 9) + floor(b / 9)) mod 9) * 9
    

    Quindi f(m, [0, 1, ..., 80])dovrebbe tornare [3, 3, 9], poiché questo gruppo è isomorfo su Z 3 × Z 3 × Z 9

Regole

  • mpuò essere una funzione (o un puntatore a una funzione) Int × Int → Into un dizionario che si associa G × Ga nuovi elementi di G.

  • fpuò prendere i suoi parametri nell'ordine opposto, cioè puoi anche implementare f(G, m).

  • L'implementazione dovrebbe teoricamente funzionare per input arbitrariamente grandi, ma non deve essere effettivamente efficiente.

  • Non ci sono limiti all'uso di built-in di alcun tipo.

  • Si applicano le regole standard del . Vince il codice più breve in byte.

Classifica

Affinché il tuo punteggio appaia sul tabellone, dovrebbe essere in questo formato:

# Language, Bytes


Se mè consentito essere un dizionario, potresti fornire anche i casi di test come dizionari?
Martin Ender,

L'ho considerato, ma sono piuttosto grandi, specialmente l'ultimo caso (migliaia di coppie chiave-valore), e non riesco a pensare a un formato molto buono per loro. Probabilmente è più facile per i rispondenti copiare le definizioni delle funzioni e quindi costruire i dizionari stessi (con qualcosa di simile for a in G: for b in G: d[(a, b)] = m(a, b)).
Lynn,

Penso che sia corretto Non riesco a dare un senso alla tua pasta abbastanza bene per verificare cosa sta succedendo, ma questo dovrebbe dimostrarlo: bpaste.net/show/5821182a9b48
Lynn

Per aiutarti a avvolgerti la testa: opera su numeri ternari con trits nel formato AABC, trattandoli come triple (A, B, C), con modulo di aggiunta a coppie (9, 3, 3).
Lynn,

Oh, ho appena realizzato il mio (molto stupido) errore. Grazie per il tuo frammento!
flawr

Risposte:


5

Matlab, 326 byte

Con alcune teorie di gruppo l'idea è abbastanza semplice: qui il TL; DR Calcola tutti i possibili ordini di elementi del gruppo. Quindi trova il sottogruppo più grande di un certo ordine di potenza principale e "fattorizzalo" dal gruppo, risciacqua, ripeti.

function r=c(h,l)

                            %factorize group order
N=numel(L);
f=factor(N);
P=unique(f);                %prime factors
for k=1:numel(P);
    E(k)=sum(f==P(k));    %exponents of unique factors
end;

                            %calculate the order O of each element
O=L*0-1; 
l=L;
for k=2:N+1;

    l=h(l,L);

    O(l==L & O<0)=k-1
end;

%%

O=unique(O);               % (optional, just for speedupt)
R=[];
                           % for each prime,find the highest power that
                           % divides any of the orders of the element, and
                           % each time substract that from the remaining
                           % exponent in the prime factorization of the
                           % group order
for p=1:nnz(P);                          % loop over primes
    while E(p)>1;                        % loop over remaining exponent
        for e=E(p):-1:1;                 % find the highest exponent
            B=mod(O,P(p)^e)==0;          
            if any(B)
                R=[R,P(p)^e];            % if found, add to list
                O(B)=O(B)/(P(p)^e);
                E(p)=E(p)-e;
                break;
            end;
        end;
    end;
    if E(p)==1;
        R=[R,P(p)];
    end;
end;
r=sort(R)

Input di esempio:

L = 0:3;
h=@(a,b)mod(a+b,4);
h=@(a,b)bitxor(a,b);
L = 0:80;
h=@(a,b)mod(mod(a,3)+mod(b,3),3)+mod(floor(a/3)+floor(b/3),3)*3+ mod(floor(a/9)+floor(b/9),9)*9; 

Versione golfizzata:

function r=c(h,l);N=numel(L);f=factor(N);P=unique(f);for k=1:numel(P);E(k)=sum(f==P(k));end;O=L*0-1;l=L;for k=2:N+1;l=h(l,L);O(l==L&O<0)=k-1;end;R=[];for p=1:nnz(P);while E(p)>1;for e=E(p):-1:1;B=mod(O,P(p)^e)==0; if any(B);R=[R,P(p)^e]; O(B)=O(B)/(P(p)^e);E(p)=E(p)-e;break;end;end;end;if E(p)==1;R=[R,P(p)];end;end;r=sort(R)

1

GAP , 159 111 byte

GAP ci consente semplicemente di costruire un gruppo da una tabella di moltiplicazione e calcolare i suoi invarianti abeliani:

ai:=    # the golfed version states the function w/o assigning it
function(m,G)
  local t;
  t:=List(G,a->List(G,b->Position(G,m(a,b))));
  # t is inlined in the golfed version
  return AbelianInvariants(GroupByMultiplicationTable(t));
end;

La vecchia versione

Il gruppo finemente presentato con generatori G e relazioni a * b = m (a, b) (per tutti a, b da G) è il gruppo (G, m) con cui abbiamo iniziato. Possiamo crearlo e calcolare i suoi invarianti abeliani con GAP:

ai:=    # the golfed version states the function w/o assigning it
function(m,G)
  local F,n,rels;
  n:=Size(G);
  F:=FreeGroup(n);
  rels:=Union(Set([1..n],i->
                Set([1..n],j->
                  F.(i)*F.(j)/F.(Position(G,m(G[i],G[j]))) ) ));
  # rels is inlined in the golfed version
  return AbelianInvariants(F/rels);
end;

Esempi

m1:=function(a,b) return (a+b) mod 4; end;
# I don't feel like implementing xor
m3:=function(a,b) return 9; end;
m4:=function(a,b)
  return (a+b) mod 3 # no need for inner mod
         + ((QuoInt(a,3)+QuoInt(b,3)) mod 3) * 3
         + ((QuoInt(a,9)+QuoInt(b,9)) mod 9) * 9;
  end;

Ora possiamo fare:

gap> ai(m1,[0..3]);
[ 4 ]

In realtà, non siamo limitati all'utilizzo di elenchi di numeri interi. Usando il dominio corretto, possiamo semplicemente usare il plus generale:

ai(\+,List(Integers mod 4));
[ 4 ]

Quindi posso essenzialmente fare il secondo esempio usando il fatto che il suo gruppo è isomorfo al gruppo additivo dello spazio vettoriale bidimensionale sul campo con 2 elementi:

gap> ai(\+,List(GF(2)^2));
[ 2, 2 ]

E gli esempi rimanenti:

gap> ai(m3,[9]);
[  ]
gap> ai(m4,[0..80]);
[ 3, 3, 9 ]

Osservazioni aggiuntive

Nella vecchia versione, m non aveva bisogno di definire una composizione di gruppo per G. Se m (a, b) = m (a, c), ciò significa che b = c. Quindi potremmo fare ai(m1,[0..5])eai(m3,[5..15]) . La nuova versione fallirà in questi casi, così come entrambe le versioni se m restituisce valori che non sono in G.

Se (G, m) non è abeliano, otteniamo una descrizione della versione abelianizzata di esso, che è il suo più grande gruppo di fattori abeliani:

gap> ai(\*,List(SymmetricGroup(4)));
[ 2 ]

Questo è ciò che AbelianInvariantsviene solitamente utilizzato, normalmente chiameremmo semplicemente AbelianInvariants(SymmetricGroup(4)).

La versione da golf

function(m,G)return AbelianInvariants(GroupByMultiplicationTable(List(G,a->List(G,b->Position(G,m(a,b))))));end
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.