mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-22 00:15:46 -07:00
New puzzle in 'unfinished'. Essentially, Sudoku for group theorists:
you are given a partially specified Cayley table of a small finite group, and must fill in all the missing entries using both Sudoku- style deductions (minus the square block constraint) and the group axioms. I've just thrown it together in about five hours by cloning- and-hacking from Keen, as much as anything else to demonstrate that the new latin.c interface really does make it extremely easy to write new Latin square puzzles. It's not really _unfinished_, as such, but it is just too esoteric (not to mention difficult) for me to feel entirely comfortable with adding it to the main puzzle collection. I can't bring myself to throw it away, though, and who knows - perhaps a university maths department might find it a useful teaching tool :-) [originally from svn r8800]
This commit is contained in:
25
unfinished/group.R
Normal file
25
unfinished/group.R
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# -*- makefile -*-
|
||||||
|
|
||||||
|
GROUP_LATIN_EXTRA = tree234 maxflow
|
||||||
|
GROUP_EXTRA = latin GROUP_LATIN_EXTRA
|
||||||
|
|
||||||
|
group : [X] GTK COMMON group GROUP_EXTRA group-icon|no-icon
|
||||||
|
|
||||||
|
group : [G] WINDOWS COMMON group GROUP_EXTRA group.res|noicon.res
|
||||||
|
|
||||||
|
groupsolver : [U] group[STANDALONE_SOLVER] latin[STANDALONE_SOLVER] GROUP_LATIN_EXTRA STANDALONE
|
||||||
|
groupsolver : [C] group[STANDALONE_SOLVER] latin[STANDALONE_SOLVER] GROUP_LATIN_EXTRA STANDALONE
|
||||||
|
|
||||||
|
ALL += group[COMBINED] GROUP_EXTRA
|
||||||
|
|
||||||
|
!begin gtk
|
||||||
|
GAMES += group
|
||||||
|
!end
|
||||||
|
|
||||||
|
!begin >list.c
|
||||||
|
A(group) \
|
||||||
|
!end
|
||||||
|
|
||||||
|
!begin >wingames.lst
|
||||||
|
group.exe:Group
|
||||||
|
!end
|
1761
unfinished/group.c
Normal file
1761
unfinished/group.c
Normal file
File diff suppressed because it is too large
Load Diff
97
unfinished/group.gap
Normal file
97
unfinished/group.gap
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# run this file with
|
||||||
|
# gap -b -q < /dev/null group.gap | perl -pe 's/\\\n//s' | indent -kr
|
||||||
|
|
||||||
|
Print("/* ----- data generated by group.gap begins ----- */\n\n");
|
||||||
|
Print("struct group {\n unsigned long autosize;\n");
|
||||||
|
Print(" int order, ngens;\n const char *gens;\n};\n");
|
||||||
|
Print("struct groups {\n int ngroups;\n");
|
||||||
|
Print(" const struct group *groups;\n};\n\n");
|
||||||
|
Print("static const struct group groupdata[] = {\n");
|
||||||
|
offsets := [0];
|
||||||
|
offset := 0;
|
||||||
|
for n in [2..31] do
|
||||||
|
Print(" /* order ", n, " */\n");
|
||||||
|
for G in AllSmallGroups(n) do
|
||||||
|
|
||||||
|
# Construct a representation of the group G as a subgroup
|
||||||
|
# of a permutation group, and find its generators in that
|
||||||
|
# group.
|
||||||
|
|
||||||
|
# GAP has the 'IsomorphismPermGroup' function, but I don't want
|
||||||
|
# to use it because it doesn't guarantee that the permutation
|
||||||
|
# representation of the group forms a Cayley table. For example,
|
||||||
|
# C_4 could be represented as a subgroup of S_4 in many ways,
|
||||||
|
# and not all of them work: the group generated by (12) and (34)
|
||||||
|
# is clearly isomorphic to C_4 but its four elements do not form
|
||||||
|
# a Cayley table. The group generated by (12)(34) and (13)(24)
|
||||||
|
# is OK, though.
|
||||||
|
#
|
||||||
|
# Hence I construct the permutation representation _as_ the
|
||||||
|
# Cayley table, and then pick generators of that. This
|
||||||
|
# guarantees that when we rebuild the full group by BFS in
|
||||||
|
# group.c, we will end up with the right thing.
|
||||||
|
|
||||||
|
ge := Elements(G);
|
||||||
|
gi := [];
|
||||||
|
for g in ge do
|
||||||
|
gr := [];
|
||||||
|
for h in ge do
|
||||||
|
k := g*h;
|
||||||
|
for i in [1..n] do
|
||||||
|
if k = ge[i] then
|
||||||
|
Add(gr, i);
|
||||||
|
fi;
|
||||||
|
od;
|
||||||
|
od;
|
||||||
|
Add(gi, PermList(gr));
|
||||||
|
od;
|
||||||
|
|
||||||
|
# GAP has the 'GeneratorsOfGroup' function, but we don't want to
|
||||||
|
# use it because it's bad at picking generators - it thinks the
|
||||||
|
# generators of C_4 are [ (1,2)(3,4), (1,3,2,4) ] and that those
|
||||||
|
# of C_6 are [ (1,2,3)(4,5,6), (1,4)(2,5)(3,6) ] !
|
||||||
|
|
||||||
|
gl := ShallowCopy(Elements(gi));
|
||||||
|
Sort(gl, function(v,w) return Order(v) > Order(w); end);
|
||||||
|
|
||||||
|
gens := [];
|
||||||
|
for x in gl do
|
||||||
|
if gens = [] or not (x in gp) then
|
||||||
|
Add(gens, x);
|
||||||
|
gp := GroupWithGenerators(gens);
|
||||||
|
fi;
|
||||||
|
od;
|
||||||
|
|
||||||
|
# Construct the C representation of the group generators.
|
||||||
|
s := [];
|
||||||
|
for x in gens do
|
||||||
|
if Size(s) > 0 then
|
||||||
|
Add(s, '"');
|
||||||
|
Add(s, ' ');
|
||||||
|
Add(s, '"');
|
||||||
|
fi;
|
||||||
|
sep := "\\0";
|
||||||
|
for i in ListPerm(x) do
|
||||||
|
chars := "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
Add(s, chars[i]);
|
||||||
|
od;
|
||||||
|
od;
|
||||||
|
s := JoinStringsWithSeparator([" {", String(Size(AutomorphismGroup(G))),
|
||||||
|
"L, ", String(Size(G)),
|
||||||
|
", ", String(Size(gens)),
|
||||||
|
", \"", s, "\"},\n"],"");
|
||||||
|
Print(s);
|
||||||
|
offset := offset + 1;
|
||||||
|
od;
|
||||||
|
Add(offsets, offset);
|
||||||
|
od;
|
||||||
|
Print("};\n\nstatic const struct groups groups[] = {\n");
|
||||||
|
Print(" {0, NULL}, /* trivial case: 0 */\n");
|
||||||
|
Print(" {0, NULL}, /* trivial case: 1 */\n");
|
||||||
|
n := 2;
|
||||||
|
for i in [1..Size(offsets)-1] do
|
||||||
|
Print(" {", offsets[i+1] - offsets[i], ", groupdata+",
|
||||||
|
offsets[i], "}, /* ", i+1, " */\n");
|
||||||
|
od;
|
||||||
|
Print("};\n\n/* ----- data generated by group.gap ends ----- */\n");
|
||||||
|
quit;
|
Reference in New Issue
Block a user