Grup Terapisi: Grupları Tanımlayın


17

Belirli sonlu magmanın çarpım tablosunun bir grubu temsil edip etmediğini belirleyen bir program yazın. Magma, ikili işlemin kapalı olduğu bir kümedir, yani

  • tüm a, b için G, a * b tekrar G'de (Kapalı)

(G, *) bir magma olsun. (G, *) aşağıdaki durumlarda gruptur:

  • G'deki tüm a, b, c için, (a * b) * c = a * (b * c) (Birliktelik)
  • G'de, e'deki tüm a için e * a = a * e = a şeklinde bir e öğesi vardır (nötr Elementin varlığı)
  • G'deki tüm a için G'de a * b = b * a = e olacak şekilde ab vardır, burada e nötr elementtir (Tersin Varlığı)

gözlük

Giriş, n ^ 2-1 karakterlik bir dizedir (magmanın her öğesi için bir karakter, izin verilen 0-9, az) ve yalnızca operatör tarafından okunan tabloyu satır satır temsil eder. Girişin geçerli bir magmayı temsil ettiğini varsayabilirsiniz (bu, öğelerin her birinin başlık satırında / sütununda tam olarak bir kez göründüğü anlamına gelir).

Örnek: Burada Z_4 tablosu var

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

Giriş dizesi olacaktır 012300123112302230133012. (Veya semboller kullanırsak da olabilir nezdnnezdeezdnzzdneddnez). Satırdaki ve sütundaki öğelerin sırasının aynı olması gerekmediğini unutmayın, bu nedenle Z_4 tablosu da şöyle görünebilir:

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

Bu aynı zamanda nötr elemanın mutlaka ilk sütunda veya ilk sırada olmadığı anlamına gelir.

Bir grupsa, program nötr elemanı temsil eden karakteri döndürmelidir. Değilse, bir falsi (0-9 az değerlerinden farklı) değeri döndürmek zorundadır

Test senaryoları

Grup olmayanlar, sadece ipin bir basamağını değiştirerek veya grup aksiyomlarından biriyle çelişen bir işlemi tanımlayan tabloları yapay olarak değiştirerek kolayca oluşturulabilir.

Gruplar

önemsiz

* | x
-----
x | x

xxx

Neutral Element: x

H (kuaterniyon grubu)

* | 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

Sigara Gruplar

Döngü (Grup eksik ilişkisi veya nötr öğeli bir Quasi-Group)

* | 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)

Bir IP döngüsü ( http://www.quasigroups.eu/contents/download/2008/16_2.pdf adresinden )

* | 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 tarafından, teşekkürler!)

Monoitler, birliğe ve nötr bir elemente sahip Magmalardır.

* | 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

Başka Bir Monoid

(Çarpım modu 10, 5 olmadan) Açıkça tersimiz yok ve çağrışım çarpma modulo 10 tarafından verilmektedir.

* | 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

Ben sadece eğlence için, daha büyük, başka bir tablo eklemek düşündüm: ideone.com/823aRG
Justin

Sadece eğlence için, 0-9a-zkuralı ihlal
Justin

Gruplar, magmalar ve benzerleri hakkında hiçbir şey bilmeyen biri için, teknik özellikler bulanık. Örneğin, operasyonlar değişmeli mi? (bu yüzden tablo gereksizdir). Dahası. ilk satırdaki nötr konumu, satır ve sütunda aynı sıraya sahip olmakla ilgili değildir: sıra 10101010aynıdır ve nötr son satır ve sütundadır
edc65 19:15

@edc Gruplar mutlaka değişmeli değildir (değişmeli gruplara abelyan denir). Bir grubun tanımı tamamlanmıştır (olağan tanımdır), ilave her şey daha fazla kısıtlama sağlayacaktır. Bu tablolarda nötr eleman ile çarpma genellikle ilk satır / sütundadır ve başlık satırı / sütunun elemanlarının sırası genellikle aynıdır, ancak bu kuralları izlemeden geçerli bir tablo yazabilirsiniz. buraya eklemek istedim.
flawr

1
Eski görünen bazı yorumları sildim. Silinmesi gereken tüm yorumlar için lütfen beni bilgilendirin.
Martin Ender

Yanıtlar:


4

Oktav, 298 290 270266 karakter

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: Gereksiz işlev tutamacı kaldırıldı.

270: Sonuçta, kontrol edilecek e==hiçin e her zaman tatmin edici e · a = ve h her zaman tatmin edici bir = bir h gerekli değildi. Farklı olmaları mümkün değildir ( e · h =? ).

Aşağıdaki çözüm açıklamasının detayları hala geçerlidir.


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);

İlk satır

c=@sortrows;d=a=c(c(reshape(a=[0 s],b=numel(a)^.5,b)')'); girdiyi nxn tablosuna (işlem işaretinin yerinde sıfır karakteriyle) depolar ve ardından satırları ve sütunları aynı sırayı alacak şekilde sütunları ve satırları sözlüksel olarak sıralar:

+ | 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

Şimdi, tabloyu verimli bir şekilde indeksleyebilmem "a","b","t","z"için standarda yeniden 1, 2, 3, 4bakıyorum. Bu çizgi ile yapılır for i=2:b a(a==a(i))=i-1;end;. Tablo gibi verir

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

, burada ilk satır ve sütundan kurtulabiliriz 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

Bu tablo verilen özelliklere sahiptir:

  • nötr eleman e varsa, tam olarak bir ( isscalar) satır ve bir sütun satır vektörü değerine sahiptir u=[1 2 3 ... number-of-elements]:

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

  • Her bir eleman ise , bir ters elemanı olan a' , iki şey tutma: nötr element e (sadece her sütun kez ve yalnızca her satır bir kez meydana gelir sum(t=a==e)==1), ve karşılamak için bir '· a · a'= , oluşumları e olan çeviriye göre simetrikt==t'

  • a · b basit t(a,b)indeksleme ile elde edilebilir. Sonra sıkıcı döngüdeki ilişkilendirmeyi kontrol ediyoruz:

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

İşlev e=d(e+1), tablo bir grubu tanımlamıyorsa , nötr öğeyi orijinal tabloda ( ) veya nil karakterinde göründüğü gibi döndürür .


2
Aferin ve iyi açıkladı. Nötr elemanı 1 yerine döndürmelidir.
edc65

Düzeltildi, şimdi uygun değeri döndürüyor.
pawel.boczarski

1
OCTAVE FTW =) İki şeyden emin değilim (matlab'dan geliyor), ama belki cevabınızı geliştirmek için kullanabilirsiniz: `a (f (a == a (i))) = i-1` azaltılabilir için a(a==a(i))=i-1? Belki kullanabilirsiniz Bunun dışında (...)^.5yerine sqrt(...).
flawr

@flawr Teşekkürler, ikisi de oktav (sürüm 3.8.1) ile çalışır.
pawel.boczarski

6

Yakut, 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}

Bu benim ilk yakut programım! Bu, yaparak test edebileceğimiz bir lambda fonksiyonunu tanımlar puts f[gets.chomp]. falseYanlış değerime geri dönüyorum. Fonksiyonun ilk yarısı, girdiyi bir haritaya ayrıştırmaktır, daha sonra ikinci yarısı olasılıkları kontrol eder.

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
Ruby'de golf harikasına hoş geldiniz! ;) nil, den daha kısa bir yanlış değerdir false. Fonksiyonlar gibi lambdas olarak tanımlanabilir q=->{abort'false'}(parametre alırlarsa, []yerine çağırmak için kullanın ()). Sana .charszaten bir dizi vermek gerektiğini düşünüyorum , bu yüzden gerek yok .to_a. Sondaki bir satırsonuna ihtiyacınız yoksa artı alandan $><<bir bayt daha kısadır puts. Hash.newparantez gerekmez. Şimdilik görebildiğim tek şey bu. Aynen böyle devam! ;)
Martin Ender

charsÇok garip. Hangi Ruby sürümünü kullanıyorsunuz?
Martin Ender

@ MartinBüttner 1.9.3
Justin

Ah, doğru, 2.1.5'in belgelerine bakıyordum.
Martin Ender

1
Sen yerini alabilir Math.sqrt(...)ile ...**0.5. Ayrıca, a if byeniden yazılabilir: b&&aiki boşluk önlemek için
Cristian Lupascu

4

JavaScript (ES6) 285 243 278

Test etmek için snippet'i çalıştırın (ES6 olarak yalnızca Firefox'ta çalışır)

Düzenle 2 Hata düzeltmesi. Nötr unsuru bulmakta yanılmıştım, sadece bir yolu kontrol ediyordum. (Daha iyi test vakalarına ihtiyacınız var !!!)

Düzenle Dizin (@Quincunx gibi) yerine daha basit dize birleştirme kullanarak, ne düşündüğümü bilmiyorum. Ayrıca, basitleştirilmiş ters kontrol, yine de çalışmalıdır.

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

Haskell 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

Lanet olsun 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

açıklama

f::String->Stringdizeyi e::Charkimlik öğesine veya ile eşleştirir !.

whereFıkra ben yorumladı ettik değişkenler ve fonksiyonlar bir demet oluşturur; v::[Int]elemanların dikey listesi h::[Int], yatay olanıdır.

%::Char->Char->Char grup işlemini argümanlarına uygular.

g::[[Int]]grup tablosudur (kayıttan kaldırma için %)

j::Maybe Intveğer varsa kimliğin indeksini içerir , aksi halde kimliğin koşulu Nothingbudur .isJust jf


Burada neler olduğunu biraz açıklayabilir misiniz?
xebtl

Birkaç yorum ekledim, ancak temel özeti 'testleri grup tablosuna uygulayın'. Bunun {- -}bir yorum olduğunu unutmayın . Daha spesifik sorularınız mı var, yoksa bu sorunu çözüyor mu?
alexander-brett

Teşekkürler. Gerçekten anlamak için tahmin ediyorum Önce bazı Haskell öğrenmek gerekir :-)
xebtl
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.