/* Blatt 2

zu Aufgabe 2:

Wir haben S5xS5 operiert auf {1..5}^2. Der zugehoerige Zykelzaehler ist: */

n:= 5;
S:= Sym(n); 
P:= PolynomialRing(Rationals(), n^2);
zz:= P ! 0;

for g,h in Classes(S) do
  cg:= CycleStructure(g[3]);
  ch:= CycleStructure(h[3]);
  factor:= P ! 1;
  for x in cg, y in ch do
    factor *:= (P.LCM(x[1], y[1]))^(GCD(x[1], y[1]) * x[2]*y[2]);
  end for;
  zz +:= g[2] * h[2] * factor;
end for;
zz /:= (#S)^2;

Q<N,E>:= PolynomialRing(Rationals(), 2);
polya:= Evaluate(zz, [N^i+E^i: i in [1..n^2]]);
Evaluate(polya, [1,1]);

// liefert die gesuchte Antwort 5624.




// Aufgabe 3

// Heute operiert A5 mal auf den Ecken, also auf A/C5.
G:= CosetImage(Alt(5), sub< Alt(5) | (1,2,3,4,5) >);

// Jetzt muessen wir die entsprechenden Kanten/Seiten finden.
Pot2:= GSet( G, Subsets({1..12}, 2));
O2:= [ o: o in Orbits(G, Pot2) | #o eq 30 ];
Kanten:= Set(O2[1]);		// Hier gibt es 2 Moeglichkeiten, beide gehen wegen ausserem Aut.

belKante:= Rep(Kanten);
Pot3:= GSet( G, Subsets({1..12}, 3));
O3:= [ x: x in Orbits(G, Pot3) | #x eq 20 and exists{ a: a in x | belKante subset a } ];
#O3;		// liefert nur 1 Moeglichkeit.
Flaechen:= Set(O3[1]);

// Damit ist der Verband fertig!
Verband:= [ {{}}, {{i}: i in [1..12]}, Kanten, Flaechen, {{1..12}} ];

AA:= MatrixRing(Integers(), 5) ! 0;
AV:= MatrixRing(Integers(), 5) ! 0;
for i,j in [1..5] do
  vj:= Rep(Verband[j]);
  AV[i,j]:= #[ x: x in Verband[i] |  x subset vj ];
  AA[i,j]:= #[ x: x in Verband[i] | vj subset  x ];
end for;
AA; ""; AV;

// Alternativ kann man AA auch aus AV ausrechnen (oder umgekehrt), denn es gilt:
X:= Matrix(Rationals(), Transpose(AA)); 
for i in [1..5] do MultiplyRow(~X, #Verband[i], i); MultiplyColumn(~X, 1/#Verband[i], i); end for; 
X eq AV;

// Jetzt zu den Seiten-Paaren:
Vector([x^2: x in Eltseq(AA[4])]) * AA^-1;     

// liefert (200  10   2   1   0), d..h

/* 1 Seitenpaar schneidet sich in einer vorgegebenen Seite,
   2 (geordnete) Seitenpaare schneiden sich in einer vorgegebenen Kante,
  10 (geordnete) Seitenpaare schneiden sich in einer vorgegebenen Ecke,
 200 (geordnete) Seitenpaare schneiden sich nicht.

 Will man ungeordnete Paare, so muss man natuerlich die Anzahlen (ausser der ersten) halbieren.


 Das Dodekaeder ist dual zum Ikosaeder, vgl. Bild. Daher korrespondieren
  Ecken Ikosaeder <-> Seiten Dodekaeder
 Kanten Ikosaeder <-> Kanten Dodekaeder
 Seiten Ikosaeder <->  Ecken Dodekaeder

 Der Schnitt zweier Seiten des Ikosaeders entspricht dem Supremum der entsprechenen Ecken etc... (*)
 Der Verband des Dodekaeders ist daher dual zum Verband des Ikosaeders 
 (Umdrehen des Verbandsdiagramms und Vertauschen der Operationen V und A).

 Daher hat der Verband des Dodekaeders auch die Matrizen AA, AV, nur in der vertauschten Reihenfolge.
 In (d) ergeben sich insbesondere dieselben Anzahlen wie schon in (b).
*/

// Alternativ, A5 operiert auf den 20 Ecken des Dodekaeders.
G:= CosetImage(Alt(5), sub< Alt(5) | (1,2,3) >);

Pot5:= GSet( G, Subsets({1..20}, 5));
Flaechen:= [ x: x in Orbits(G, Pot5) | #x eq 12 ][1];	// 2 Moegl. beides ok.
Pot2:= GSet( G, Subsets({1..20}, 2));
Kanten:= [ o: o in Orbits(G, Pot2) | #o eq 30 and exists{a: a in o | a subset Flaechen[1]} ][1];
Verband:= [ {{}}, {{i}: i in [1..20]}, Kanten, Flaechen, {{1..20}} ];

BA:= MatrixRing(Integers(), 5) ! 0;
BV:= MatrixRing(Integers(), 5) ! 0;
for i,j in [1..5] do
  vj:= Rep(Verband[j]);
  BV[i,j]:= #[ x: x in Verband[i] |  x subset vj ];
  BA[i,j]:= #[ x: x in Verband[i] | vj subset  x ];
end for;

// Beachte, wir haben nun eine andere Reihenfolge der Bahnen. Das korrigieren wir durch konjugation mit J.
J:= MatrixRing(Rationals(), 5) ! 0; for j in [1..5] do J[6-j, j]:= 1; end for;
BA eq J*AV*J^-1; BV eq J*AA*J^-1;

