그룹 치료 : 그룹 식별


17

주어진 유한 마그마의 곱셈 테이블이 그룹을 나타내는 지 여부를 결정하는 프로그램을 작성하십시오. 마그마는 이진 연산이 닫힌 세트입니다.

  • 모든 a, b에 대해 G에서 a * b는 다시 G에 있습니다 (폐쇄)

(G, *)를 마그마로 둡니다. (G, *)는

  • G에서 모든 a, b, c에 대해, (a * b) * c = a * (b * c) (연관성)
  • G에 e가 존재하여 G에있는 모든 a에 대해 e * a = a * e = a가 존재 함 (중립 원소의 존재)
  • G의 모든 a에 대해 a * b = b * a = e와 같이 G에 ab가 있습니다.

명세서

입력은 n ^ 2-1 문자의 문자열 (마그마의 각 요소에 대해 한 문자, 0-9, az 허용)이며 행별로 읽은 테이블을 나타내며 연산자 이름은 생략합니다. 입력이 유효한 마그마를 나타내는 것으로 가정 할 수 있습니다 (즉, 각 요소가 헤더 행 / 열에 정확히 한 번 적용됨을 의미).

예 : 여기 Z_4 테이블이 있습니다

+ | 0 1 2 3
-----------
0 | 0 1 2 3
1 | 1 2 3 0
2 | 2 3 0 1
3 | 3 0 1 2

입력 문자열은입니다 012300123112302230133012. (또는 기호를 사용하는 경우도 가능 nezdnnezdeezdnzzdneddnez) 행과 열의 요소 순서가 같을 필요는 없으므로 Z_4 테이블은 다음과 같이 보일 수 있습니다.

+ | 1 3 2 0
-----------
1 | 2 0 3 1
0 | 1 3 2 0
2 | 3 1 0 2
3 | 0 2 1 3

이는 또한 중립 요소가 반드시 첫 번째 열 또는 첫 번째 행에있는 것은 아님을 의미합니다.

그룹 인 경우 프로그램은 중립 요소를 나타내는 문자를 리턴해야합니다. 그렇지 않은 경우 거짓 (값 0-9 az와 구별됨) 값을 리턴해야합니다.

테스트 사례

비 그룹은 문자열의 한 자리 만 변경하거나 그룹 공리 중 하나와 모순되는 작업을 정의하는 테이블을 인위적으로 변경하여 쉽게 구성 할 수 있습니다.

여러 떼

하찮은

* | x
-----
x | x

xxx

Neutral Element: x

H (쿼터니언 그룹)

* | p t d k g b n m 
-------------------
m | b d t g k p m n 
p | m k g d t n p b 
n | p t d k g b n m 
b | n g k t d m b p 
t | g m n p b k t d 
d | k n m b p g d t 
k | t b p m n d k g 
g | d p b n m t g k 

ptdkgbnmmbdtgkpmnpmkgdtnpbnptdkgbnmbngktdmbptgmnpbktddknmbpgdtktbpmndkggdpbnmtgk

Neutral Element: n

D_4

* | y r s t u v w x
-------------------
u | u x w v y t s r
v | v u x w r y t s
w | w v u x s r y t
x | x w v u t s r y
y | y r s t u v w x
r | r s t y v w x u
s | s t y r w x u v
t | t y r s x u v w


yrstuvwxuuxwvytsrvvuxwrytswwvuxsrytxxwvutsryyyrstuvwxrrstyvwxusstyrwxuvttyrsxuvw

Neutral Element: y

Z_6 x Z_2

x | 0 1 2 3 5 7 8 9 a b 4 6
---------------------------
0 | 0 1 2 3 5 7 8 9 a b 4 6 
1 | 1 2 3 4 0 8 9 a b 6 5 7 
2 | 2 3 4 5 1 9 a b 6 7 0 8 
7 | 7 8 9 a 6 2 3 4 5 0 b 1 
8 | 8 9 a b 7 3 4 5 0 1 6 2 
9 | 9 a b 6 8 4 5 0 1 2 7 3 
a | a b 6 7 9 5 0 1 2 3 8 4 
b | b 6 7 8 a 0 1 2 3 4 9 5 
3 | 3 4 5 0 2 a b 6 7 8 1 9 
4 | 4 5 0 1 3 b 6 7 8 9 2 a 
5 | 5 0 1 2 4 6 7 8 9 a 3 b 
6 | 6 7 8 9 b 1 2 3 4 5 a 0 

01235789ab46001235789ab4611234089ab6572234519ab67087789a623450b1889ab7345016299ab684501273aab6795012384bb678a0123495334502ab67819445013b67892a5501246789a3b66789b12345a0

Neutral Element: 0

A_4

* | i a b c d e f g h j k l
---------------------------
i | i a b c d e f g h j k l
a | a b i e c d g h f l j k
b | b i a d e c h f g k l j
c | c f j i g k a d l b e h
d | d h k b f l i e j a c g
e | e g l a h j b c k i d f
f | f j c k i g d l a h b e
g | g l e j a h c k b f i d
h | h k d l b f e j i g a c
j | j c f g k i l a d e h b
k | k d h f l b j i e c g a
l | l e g h j a k b c d f i

iabcdefghjkliiabcdefghjklaabiecdghfljkbbiadechfgkljccfjigkadlbehddhkbfliejacgeeglahjbckidfffjckigdlahbegglejahckbfidhhkdlbfejigacjjcfgkiladehbkkdhflbjiecgalleghjakbcdfi

Neutral Element: i

비 그룹

루프 (그룹 누락 연관성 또는 중립 요소가있는 준 그룹)

* | 1 2 3 4 5
-------------
1 | 1 2 3 4 5 
2 | 2 4 1 5 3 
3 | 3 5 4 2 1 
4 | 4 1 5 3 2 
5 | 5 3 2 1 4

12345112345224153335421441532553214

Neutral Element: 1
(2*2)*3 = 4*3 = 5 != 2 = 2*1 = 2*(2*3)

IP 루프 ( http://www.quasigroups.eu/contents/download/2008/16_2.pdf에서 제공 )

* | 1 2 3 4 5 6 7
-----------------
1 | 1 2 3 4 5 6 7
2 | 2 3 1 6 7 5 4
3 | 3 1 2 7 6 4 5
4 | 4 7 6 5 1 2 3
5 | 5 6 7 1 4 3 2
6 | 6 4 5 3 2 7 1
7 | 7 5 4 2 3 1 6

123456711234567223167543312764544765123556714326645327177542316

Neutral Element: 1
2*(2*4) = 2*6 = 5 != 7 = 3*4 = (2*2)*4

Monoid (Quincunx 제작, 감사합니다!)

모노 이드는 연관성과 중립 요소를 가진 마그마입니다.

* | 0 1 2 3
-----------
0 | 0 1 2 3
1 | 1 3 1 3
2 | 2 1 0 3
3 | 3 3 3 3

012300123113132210333333

Neutral Element: 0

다른 모노 이드

(5가없는 곱셈 mod 10) 우리는 분명히 반비가 없으며, 곱셈 modulo 10에 의해 연관성이 주어진다.

* | 1 2 3 4 6 7 8 9
-------------------
1 | 1 2 3 4 6 7 8 9
2 | 2 4 6 8 2 4 6 8
3 | 3 6 9 2 8 1 4 7
4 | 4 8 2 6 4 8 2 6
6 | 6 2 8 4 6 2 8 4
7 | 7 4 1 8 2 9 6 3
8 | 8 6 4 2 8 6 4 2
9 | 9 8 7 6 4 3 2 1

Neutral Element: 1   12346789112346789224682468336928147448264826662846284774182963886428642998764321


재미를 위해, 여기 0-9a-z규칙 을 어기는 또 다른 큰 것이 있습니다 : ideone.com/vC0ewt
Justin

그룹, 마마 등에 대해 전혀 모르는 사람에게는 사양이 흐릿합니다. 예를 들어, 작업은 정식입니까? (따라서 테이블은 중복됩니다). 게다가. 첫 번째 행에서 중립의 위치는 행과 열에서 동일한 순서를 갖는 것과 관련이 없습니다 10101010. 순서가 동일하고 중립이 마지막 행과 열에 있습니다
edc65

@edc 그룹은 반드시 정식적인 것은 아닙니다 (정류 그룹은 abelian이라고합니다). 그룹의 정의가 완료되었습니다 (일반적인 정의 임). 추가 항목이 있으면 추가 제한 사항이 제공됩니다. 이 테이블에서 중립 요소의 곱셈은 일반적으로 첫 번째 행 / 열에 있으며 헤더 행 / 열의 요소 순서는 일반적으로 동일하지만 이러한 규칙을 따르지 않고 유효한 테이블을 계속 쓸 수 있습니다. 여기에 포함하고 싶었습니다.
flawr

1
쓸모없는 것으로 보이는 일부 의견을 삭제했습니다. 삭제를 취소해야하는 의견이 있으면 알려주십시오.
마틴 엔더

답변:


4

옥타브, 298290270265 문자

function e=g(s)
c=@sortrows;d=a=c(c(reshape(a=[0 s],b=numel(a)^.5,b)')');
for i=2:b a(a==a(i))=i-1;end;
a=a(2:b,2:b--);u=1:b;
e=(isscalar(e=find(all(a==u')))&&a(e,:)==u&&sum(t=a==e)==1&&t==t')*e;
for x=u for y=u for z=u e*=a(a(x,y),z)==a(x,a(y,z));end;end;end;e=d(e+1);

265 : 불필요한 기능 핸들이 제거되었습니다.

270 : 결국, 체크 것을 e==h위해 전자 항상 만족 전자 · A는을 =시간은 항상 만족 A는 = A · 시간을 필요하지 않았다. 그것들이 다를 수는 없다 ( e · h =? ).

아래 솔루션에 대한 설명의 세부 사항은 여전히 ​​관련이 있습니다.


290 :

function e=g(s)
c=@sortrows;d=a=c(c(reshape(a=[0 s],b=numel(a)^.5,b)')');
for i=2:b a(a==a(i))=i-1;end;
a=a(2:b,2:b--);u=1:b;
s=@isscalar;e=(s(e=find(all(a==u')))&&s(h=find(all(a'==u')'))&&sum(t=a==e)==1&&t==t')*e;
for x=u for y=u for z=u e*=a(a(x,y),z)==a(x,a(y,z));end;end;end;e=d(e+1);

첫 줄

c=@sortrows;d=a=c(c(reshape(a=[0 s],b=numel(a)^.5,b)')'); 입력을 nxn 테이블에 저장 한 다음 (작업 표시 위치에 문자가없는) 행과 열이 동일한 순서를 갖도록 사전 순으로 열과 행을 정렬합니다.

+ | z a t b                        + | a b t z
-----------                        -----------
z | t b a z         becomes        a | t a z b
b | z a t b      ============>     b | a b t z
t | a z b t                        t | z t b a
a | b t z a                        z | b z a t

이제 표를 효율적으로 색인 할 수 있도록 "a","b","t","z"standard로 다시 매핑 합니다 1, 2, 3, 4. 이것은 라인에 의해 수행됩니다 for i=2:b a(a==a(i))=i-1;end;. 그것은 같은 테이블을 산출

0   1   2   3   4
1   3   1   4   2
2   1   2   3   4
3   4   3   2   1
4   2   4   1   3

을 사용하여 첫 번째 행과 열을 제거 할 수 있습니다 a=a(2:b,2:b--);u=1:b;.

3  1  4  2
1  2  3  4
4  3  2  1
2  4  1  3

이 테이블에는 주어진 속성이 있습니다.

  • 중립 요소 경우 전자가 존재하는 단 하나의 ( isscalar)의 행 및 하나의 열은 행 벡터의 값을 갖는다 u=[1 2 3 ... number-of-elements]:

s=@isscalar;e=(s(e=find(all(a==u')))&&s(h=find(all(a'==u')'))&&...

  • 각 요소 a 에 역 요소 a '가있는 경우 두 가지가 있습니다. 중립 요소 e 는 각 열마다 한 번만 발생하고 (a sum(t=a==e)==1) a'· a = a · a ' 를 충족 하기 위해 e 의 발생은 다음과 같습니다. 번역과 관련하여 대칭t==t'

  • 간단한 t(a,b)인덱싱 으로 a · b를 검색 할 수 있습니다 . 그런 다음 보링 루프에서 연관성을 확인합니다.

for x=u for y=u for z=u e*=a(a(x,y),z)==a(x,a(y,z));end;end;end;

이 함수는 e=d(e+1)그룹이 설명되지 않은 경우 원래 테이블 ( ) 또는 nil 문자에 나타난 방식으로 중립 요소를 반환합니다 .


2
잘하고 잘 설명했다. 1 대신에 중립 요소를 반환해야합니다.
edc65

수정되었습니다. 이제 적절한 값을 반환합니다.
pawel.boczarski

1
OCTAVE FTW =) 나는 matlab에서 오는 두 가지에 대해 확신하지 못하지만 아마도 대답을 향상시키기 위해 그것을 사용할 수 있습니다 :`a (f (a == a (i))) = i-1` 에 a(a==a(i))=i-1? 그 외에는 (...)^.5대신에 사용할 수도 있습니다 sqrt(...).
flawr

@flawr 감사합니다. 둘 다 옥타브 (버전 3.8.1)로 작동합니다.
pawel.boczarski

6

루비, 401 ... 272

f=->s{n=(s.size+1)**0.5
w=n.to_i-1
e=s[0,w].split''
s=s[w,n*n]
m={}
w.times{(1..w).each{|i|m[s[0]+e[i-1]]=s[i]}
s=s[n,n*n]}
s=e.find{|a|e.all?{|b|x=m[a+b]
x==m[b+a]&&x==b}}
e.all?{|a|t=!0
e.all?{|b|x=m[a+b]
t||=x==m[b+a]&&x==s
e.all?{|c|m[m[a+b]+c]==m[a+m[b+c]]}}&&t}&&s}

이것은 나의 첫번째 루비 프로그램입니다! 이를 통해 테스트 할 수있는 람다 함수를 정의합니다 puts f[gets.chomp]. 나는 false나의 허위 가치를 위해 돌아온다 . 함수의 전반부는 단순히 입력을 맵으로 파싱하고, 후반은 가능성을 점검합니다.

f=->s{
    n=((s.size+1)**0.5).to_i
    w=n-1
    e=s[0,w].split'' # create an array of elements of the potential group
    s=s[w,n*n]
    m={} # this map is what defines our operation
    w.times{
        (1..w).each{               # for each element in the row of the table
            |i|m[s[0]+e[i-1]]=s[i] # put the value into the map
        }
        s=s[n,n*n]
    }
    s=e.find{|a| # s is the identity
        e.all?{|b|
            x=m[a+b]
            x==m[b+a]&&x==b # is a the identity?
        }
    }
    e.all?{|a| # implicit return statement
        t = !0 # t = false
        e.all?{|b| # check for inverses
            x=m[a+b]
            t ||= x==m[b+a]&&x==s # t is now true if b was a's inverse
            e.all?{|c|
                m[m[a+b]+c]==m[a+m[b+c]] # check associativity
            }
        } && t
    }&&s
}

5
루비 골프의 경이로움을 환영합니다! ;) nil은 (는)보다 잘못된 값 false입니다. 함수는 람다로 정의 할 수 있습니다 q=->{abort'false'}(매개 변수를 사용 []하는 경우 대신 을 사용 하여 호출 ()). 나는 .chars이미 배열을 제공해야 한다고 생각 하므로 필요하지 않습니다 .to_a. 후행 줄 바꿈 $><<이 필요하지 않으면 puts더하기 공백 보다 1 바이트 짧습니다 . Hash.new괄호가 필요하지 않습니다. 그것이 내가 지금 볼 수있는 전부입니다. 유지하십시오! ;)
Martin Ender

chars것은 이상하다. 어떤 루비 버전을 사용하고 있습니까?
Martin Ender

@ MartinBüttner 1.9.3
저스틴

아, 맞아, 나는 2.1.5의 문서를보고있다.
Martin Ender 2016

1
당신은 대체 할 수 있습니다 Math.sqrt(...)...**0.5. 또한, a if b다시 쓸 수 있습니다 : b&&a두 공간을 피하기 위해
Cristian Lupascu

4

자바 스크립트 (ES6) 285 243 278

스 니펫을 실행하여 테스트하십시오 (ES6이므로 Firefox에서만 작동 함).

2 버그 수정을 편집 하십시오. 나는 중립 요소를 찾는 데 잘못되었고 한 가지 방법 만 확인했습니다. (더 나은 테스트 사례가 필요합니다 !!!)

편집 @Quincunx와 같은 이중 인덱스 대신 간단한 문자열 연결을 사용하여 내가 생각한 것을 알지 못합니다. 또한 단순화 된 역 검사는 여전히 작동합니다.

F=t=>(
  e=t.slice(0,d=Math.sqrt(t.length)|0),
  t=t.slice(d).match('.'.repeat(d+1),'g'),
  t.map(r=>{
    for(v=r[i=0],
        j=e.search(v)+1, // column for current row  element
        r!=v+e|t.some(r=>r[j]!=r[0])?0:n=v; // find neutral
        c=r[++i];
       )h[v+e[i-1]]=c
  },h={},n=''),
  e=[...e],!e.some(a=>e.some(b=>(
    h[a+b]==n&&--d, // inverse
    e.some(c=>h[h[a+b]+c]!=h[a+h[b+c]]) // associativity
  )
  ))&&!d&&n
)
input { width: 400px; font-size:10px }
Click on textbox to test - Result : <span id=O></span><br>
<input value='...' onclick='O.innerHTML=F(this.value)'> (?)
<br>Groups<br>
<input value='nezdnnezdeezdnzzdneddnez' onclick='O.innerHTML=F(this.value)'> (n)<br>
<input value='ptdkgbnmmbdtgkpmnpmkgdtnpbnptdkgbnmbngktdmbptgmnpbktddknmbpgdtktbpmndkggdpbnmtgk' onclick='O.innerHTML=F(this.value)'> (n)<br>
<input value='yrstuvwxuuxwvytsrvvuxwrytswwvuxsrytxxwvutsryyyrstuvwxrrstyvwxusstyrwxuvttyrsxuvw' onclick='O.innerHTML=F(this.value)'> (y)<br>
<input value='01235789ab46001235789ab4611234089ab6572234519ab67087789a623450b1889ab7345016299ab684501273aab6795012384bb678a0123495334502ab67819445013b67892a5501246789a3b66789b12345a0'onclick='O.innerHTML=F(this.value)'> (0)<br>
Non groups <br>
<input value='12345112345224153335421441532553214' onclick='O.innerHTML=F(this.value)'> (FAIL)<br>
<input value='123456711234567223167543312764544765123556714326645327177542316' onclick='O.innerHTML=F(this.value)'> (FAIL)<br>
<input value='012300123113132210333333' onclick='O.innerHTML=F(this.value)'> (FAIL)<br>


2

하스켈 391B

import Data.Maybe
import Data.List
o a b=elemIndex b a
l£a=fromJust.o a$l
a§b=[a!!i|i<-b]
f s|isJust j&&and(map(isJust.o h)s)&&and[or[p%q==e|q<-h]&&and[p%(q%r)==(p%q)%r|q<-h,r<-h]|p<-h]=[e]|True="!"where n=floor$(sqrt(fromIntegral$length s+1))-1;h=take n s;g=[s§[a..b]|(a,b)<-zip[1+n,2+n+n..][n+n,3*n+1..(n+1)^2]];v=s§[n,1+2*n..n+n*n];a%b=g!!(b£v)!!(a£h);j=o g h;e=v!!fromJust j

저주 import !

import Data.Maybe
import Data.List

{- rename elemIndex to save characters -}
o a b=elemIndex b a

{- get the index of l in a -}
l£a=fromJust.o a$l

{- extract a sublist of a with indices b -}
a§b=[a!!i|i<-b]

f s |isJust j {-Identity-}
     &&and (map (isJust.o h) s) {-Closure-}
     &&and[
        or [p%q==e|q<-h] {-Inverse-}
        && and [ p%(q%r)==(p%q)%r | q<-h,r<-h ] {-Associativity-}
     |
        p<-h
     ]=[e]
    |True="!"
    where
    {-size-}    n=floor$(sqrt(fromIntegral$length s+1))-1
    {-horiz-}   h=take n s
    {-table-}   g=[s§[a..b]|(a,b)<-zip[1+n,2+n+n..][n+n,3*n+1..(n+1)^2]]
    {-vert-}    v=s§[n,1+2*n..n+n*n]
    {-operate-} a%b=g!!(b£v)!!(a£h)
                j=o g h {-index of the first row identical to the top-}
    {-ident-}   e=v!!fromJust j

설명

f::String->String 문자열을 e::Char , identity 요소 또는로! .

where절은 내가 언급 한 많은 변수와 함수를 만듭니다.v::[Int]요소의 세로 목록, h::[Int]가로 요소 입니다.

%::Char->Char->Char 그룹 작업을 해당 인수에 적용합니다.

g::[[Int]]그룹 테이블입니다 (를 사용하여 역참 조용 %).

j::Maybe Int의 ID의 인덱스 포함 v, 그렇지 않으면, 존재하는 경우를 Nothing이유입니다, isJust j의 조건 f정체성.


여기서 무슨 일이 일어나고 있는지 조금 설명해 주시겠습니까?
xebtl

몇 가지 의견을 추가했지만 기본 요점은 '테스트를 그룹 테이블에 적용'입니다. 참고 {- -}주석입니다. 더 구체적인 질문이 있습니까, 아니면 명확합니까?
alexander-brett

감사. 나는 :-) 처음 몇 하스켈을 배울 필요가 정말 이해하는 것 같아요
xebtl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.