查找有限组的子组数


14

定义

如果您已经知道有限组的定义,则可以跳过此部分。

团体

在抽象代数中,一个是一个元组(G,∗),其中G是一个集合,而是一个函数G×G→G,使得下式成立:

  • 封闭:对于所有的x,yģX * Y也是ģ(由事实暗示*是一个函数G×G ^→G )。

  • 关联:对所有X,Y,Zģ(X * Y)* Z = X *(Y * Z)

  • 同一性:存在一个元素êģ使得对于所有XģX * E = X = E * X

  • 逆:对于每个Xģ,存在一个元素ýģ使得X * Y = E = Y * X,其中ê是在前面的项目符号点中提到的单位元。

有限群体

有限组是一组(G,*) ,其中G ^是有限的,即,具有有限多个元件。

亚组

(G,∗)子组 (H,∗)使得HG的子集(不一定是适当的子集),而(H,∗)也是一个组(即满足上述4个条件)。

例子

考虑二面体组D 3 (G,∗),其中G = {1,A,B,C,D,E},并且在下面定义(这样的表称为Cayley表):

∗ | 1个ABCDE
-+ ----------------------
1 | 1个ABCDE
A | AB 1 DEC
B | B 1 AECD
C | CED 1 BA
D | DCEA 1 B
E | EDCBA 1

在这个组中,身份为1。另外,是彼此的逆,而1Çd,和Ë本身的分别的倒数(的倒数11,逆ÇÇ,的倒数dd,并且E的倒数是E)。

现在,我们可以验证其中H = {1,A,B}的(H,∗)(G,∗)的子组。对于关闭,请参考下表:

∗ | 1 AB
-+ ----------
1 | 1 AB
A | AB 1
B | B 1 A

其中所有可能的对中元件的ħ*给在一个成员ħ

关联性不需要检查,因为H的元素是G的元素。

身份是1。与组标识必须相同。同样,组中的身份必须唯一。(你能证明这个吗?)

对于逆,请检查A的逆是B,它是H的成员。B的倒数是A,它也是H的成员。1的倒数本身仍然是,不需要检查。


任务

描述

给定一个有限群(G,∗),找到其子群的数量。

输入值

对于一个组(G,∗),您将收到一个大小为n×n的二维数组,其中nG中的元素数。假设索引0是标识元素。2D数组将代表乘法表。例如,对于上面的组,您将收到以下2D数组:

[[0, 1, 2, 3, 4, 5],
[1, 2, 0, 4, 5, 3],
[2, 0, 1, 5, 3, 4],
[3, 5, 4, 0, 2, 1],
[4, 3, 5, 1, 0, 2],
[5, 4, 3, 2, 1, 0]]

例如,您可以看到3 ∗ 1 = 5,因为a[3][1] = 5a上面的2D数组在哪里。

笔记:

  • 您可以使用1索引2D数组。
  • 标识的行和列可以省略。
  • 您可以视需要使用其他格式,但必须保持一致。(即,您可能希望最后一个索引改为标识,等等)

输出量

代表组中子组数的正数。

例如,对于上面的组,每当H =(H,∗)(G,∗)的子组

  • {1}
  • {1,A,B}
  • {1,C}
  • {1,D}
  • {1,E}
  • {1,A,B,C,D,E}

因此,有6个子组,此示例的输出应为6


提示

您可以阅读我链接到的文章。这些文章包含有关组和子组的定理,这可能对您有用。


计分

这是。以最低字节数获胜的答案。


哦,对我来说还不清楚,e专门指代身份元素,而不仅仅是任何中间结果。
orlp

@orlp澄清。
Leaky Nun

如果要调用0标识元素,那么将运算符描述为乘法会令人困惑...
Neil

@Neil eh ...当约定冲突时。
Leaky Nun

1
我假设2D列表中的元素与它们的行/列的索引相同,否则您将如何确定哪个行/列与哪个行对应?
与Orjan约翰森

Answers:


8

Mathematica,62个48字节

Count[Subsets@First@#,x_/;Union@@#[[x,x]]==x]-1&

纯函数需要1索引的2D数组。Counts在分组操作下关闭的输入数组SubsetsFirst行数。由于这将包括空集,因此我们减去1。请注意,在组操作下关闭的有限组的非空子集实际上是一个子组(反之亦然,根据定义)。

严格来说,我不检查x是否在组操作下关闭了子集,而是将乘法表限制为子集,x并检查它是否恰好包含的元素x。显然,这意味着x对于组操作是封闭的。相反,任何子组x都将包含1并且因此x将是出现在受限乘法表中的元素的子集,并且由于x在组操作下被关闭,因此它必须等于x


4

Haskell,79个字节

基本上是人种的Mathematica方法的端口。(除了我使用的是0索引数组。)

c接受Ints 的列表并返回一个整数。

c g=sum[1|l<-foldr(\r->([id,(r!!0:)]<*>))[[]]g,and[g!!x!!y`elem`l|x<-l,y<-l]]-1

在线尝试!

假定Ints的编号与显示其相乘的行(外部列表)和列的编号相同。因此,由于0是标识,因此第一列与行的索引相同。这允许使用第一列的条目来构造子集。

怎么运行的

  • c 是主要功能。
  • g 是作为列表列表的组数组。
  • l是元素的子集。子集列表的构造如下:
    • foldr(\r->([id,(r!!0:)]<*>))[[]]g在的行上折叠一个函数g
    • r是的一行g,其第一个(0th)元素被提取为可能包含((r!!0:))或不包含()的元素id
    • <*> 结合了该行的选择和随后的选择。
  • and[g!!x!!y`elem`l|x<-l,y<-l]测试每对元素l的倍数是否在l
  • sum[1|...]-1 对通过测试的子集进行计数,除了一个空子集。

3

果冻17 16字节

1个字节归功于ETHproductions(LR → J

ị³Z⁸ịFḟ
JŒPÇÐḟL’

JŒPÇÐḟL’  main link. one argument (2D array)
J         [1,2,3,...,length of argument]
 ŒP       power set of ^
    Ðḟ    throw away elements that pass the test...
   Ç      in the helper link
      L   length (number of elements that do not pass)
       ’  decrement (the empty set is still closed under
          multiplication, but it is not a subgroup, as
          the identity element does not exist.)

ị³Z⁸ịFḟ   helper link. one argument (1D indexing array)
ị³        elements at required indices of program input (2D array)
  Z       transpose
   ⁸ị     elements at required indices of ^
     F    flatten
      ḟ   remove elements of ^ that are in the argument given
          if the set is closed under multiplication, this will
          result in an empty set, which is considered falsey.

在线尝试!(1索引)


您可以做J而不是LR保存一个字节:-)
ETHproductions'Apr 26'17

@ETHproductions哇,谢谢你发现这一点。
Leaky Nun

3

Python 2中,297个 215字节

from itertools import*
T=input()
G=T[0]
print sum(all(T[y][x]in g for x,y in product(g,g))*all(any(T[y][x]==G[0]==T[x][y]for y in g)for x in g)*(G[0]in g)for g in chain(*[combinations(G,n)for n in range(len(G)+1)]))

在线尝试

该程序适用于不带的示例组==T[x][y],但是我仍然很确定它是必需的。

编辑:现在假定G的标识元素始终是第一个。


取消高尔夫:

from itertools import*
T=input()
G=T[0]
def f(x,y):return T[y][x]                                           # function
def C(g):return all(f(x,y)in g for x,y in product(g,g))             # closure
def E(g):return[all(f(x,y)==y for y in g)for x in g]                # identity

a=E(G)
e=any(a)
e=G[a.index(1)]if e else-1                                          # e in G

def I(G):return all(any(f(x,y)==e==f(y,x)for y in G)for x in G)     # inverse

#print e
#print C(G),any(E(G)),I(G)

#for g in chain(*[combinations(G,n)for n in range(len(G)+1)]):      # print all subgroups
#   if C(g)and I(g)and e in g:print g

print sum(C(g)*I(g)*(e in g)for g in chain(*[combinations(G,n)for n in range(len(G)+1)]))

空缺的TIO

-1改为可以免费支持负组元素''


为什么要检查身份?身份保证是第一要素。只需进行没有第一个元素的所有组合,然后将第一个元素添加到每个组合中即可。
orlp

“假设0是标识元素。”
orlp

是的,但这并不意味着它在列表中排名第一。我认为这是在谈论0示例的编号,而不是索引。
mbomb007 '17

@ mbomb007显然是指数
Leaky Nun
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.