Grup
Dalam aljabar abstrak, grup adalah tupel , di mana adalah himpunan dan adalah fungsi sedemikian rupa sehingga berlaku sebagai berikut:
Untuk semua dalam , .
Ada elemen di sehingga untuk semua di , .
Untuk setiap dalam , ada elemen di sehingga .
The rangka dari kelompok didefinisikan sebagai jumlah elemen dari .
Untuk setiap bilangan bulat positif , ada setidaknya satu kelompok pesanan n . Sebagai contoh, ( C n , + n ) adalah kelompok seperti itu, di mana C n = { 0 , . . . , n - 1 } dan x + n y = ( x + y ) .
Kelompok isomorfik
Biarkan dan tentukan ∗ oleh x ∗ y = ( x × y ) . Kemudian 1 ∗ 1 = 1 = 2 ∗ 2 dan 1 ∗ 2 = 2 = 2 ∗ 1 .
Demikian juga, dan 0 + 2 1 = 1 = 1 + 2 0 .
Meskipun elemen dan operasi grup dan ( C 2 , + 2 ) memiliki nama yang berbeda, grup memiliki struktur yang sama.
Dua kelompok dan ( G 2 , ∗ 2 ) dikatakan isomorfik jika ada penambangan ϕ : G 1 → G 2 sedemikian rupa sehingga ϕ ( x ∗ 1 y ) = ϕ ( x ) ∗ 2 ϕ ( y ) untuk semua x , y dalam G 1 .
Tidak semua kelompok dengan urutan yang sama isomorfik. Sebagai contoh, kelompok Klein adalah sekelompok order 4 yang tidak isomorfis ke .
Tugas
Tulis program atau fungsi yang menerima bilangan bulat non-negatif n sebagai input dan mencetak atau mengembalikan jumlah kelompok urutan non-isomorfik n .
Uji kasus
Input Output
0 0
1 1
2 1
3 1
4 2
5 1
6 2
7 1
8 5
9 2
10 2
11 1
12 5
13 1
14 2
15 1
16 14
17 1
18 5
19 1
20 5
(diambil dari OEIS A000001 )
Aturan tambahan
Tidak ada batasan waktu eksekusi atau penggunaan memori.
Built-in yang meremehkan tugas ini, seperti Mathematica
FiniteGroupCount
, tidak diperbolehkan.Aturan standar kode-golf berlaku.
sumber
monkeys_on_typewriters
builtin yang tidak berdokumen mencakup semua yang tidak tercakup oleh builtin yang terdokumentasi.Jawaban:
CJam,
189187 byteYang ini akan sulit dijelaskan ... Kompleksitas waktu dijamin
O(scary)
.Jika Anda cukup berani, cobalah secara online . Di laptop jelek saya, saya bisa mendapatkan hingga 6 dengan juru bahasa Java atau 5 di juru bahasa online.
Penjelasan
Saya tidak memiliki latar belakang matematika yang besar (baru lulus SMA, mulai CS di universitas minggu depan). Jadi bersabarlah jika saya melakukan kesalahan, nyatakan yang jelas, atau lakukan hal-hal dengan cara yang sangat tidak efisien.
Pendekatan saya adalah kekuatan kasar, meskipun saya mencoba membuatnya sedikit lebih pintar. Langkah-langkah utamanya adalah:
Sebelum melihat bagaimana setiap langkah dilakukan, mari kita buat beberapa kode sepele:
Algoritma berikut tidak bekerja dengan benar dengan n <4 , kasing dari 0 ke 3 ditangani dengan negasi ganda.
Mulai sekarang, elemen-elemen grup akan ditulis sebagai {1, a, b, c, ...} , di mana 1 adalah elemen identitas. Dalam implementasi CJam, elemen yang sesuai adalah {0, 1, 2, 3, ...} , di mana 0 adalah elemen identitas.
Mari kita mulai dari langkah 1. Menulis semua operator yang memungkinkan untuk sekelompok pesanan n setara dengan menghasilkan semua tabel Cayley n × n yang valid . Baris dan kolom pertama sepele: keduanya {1, a, b, c, ...} (kiri-ke-kanan, atas-ke-bawah).
Mengetahui bahwa tabel Cayley juga merupakan kotak Latin yang diperkecil (karena properti pembatalan) memungkinkan untuk menghasilkan tabel yang mungkin baris-demi-baris. Mulai dari baris kedua (indeks 1), kami menghasilkan semua permutasi unik untuk baris itu, menjaga kolom pertama tetap pada nilai indeks.
Tidak semua permutasi itu valid, tentu saja: setiap baris dan kolom harus berisi semua elemen tepat satu kali. Blok filter digunakan untuk tujuan ini (nilai kebenaran menjaga permutasi, yang salah menghapusnya):
Perhatikan bahwa saya memfilter di dalam loop generasi: ini membuat kode sedikit lebih lama (dibandingkan dengan generasi berbeda dan pemfilteran), tetapi sangat meningkatkan kinerja. Jumlah permutasi dari satu set ukuran n adalah n! , jadi solusi yang lebih pendek tentu membutuhkan banyak memori dan waktu.
Daftar tabel Cayley yang valid adalah langkah bagus untuk menghitung operator, tetapi sebagai struktur 2D, ia tidak dapat memeriksa asosiatif, yang merupakan properti 3D. Jadi langkah selanjutnya adalah menyaring fungsi non-asosiatif.
Fiuh! Banyak pekerjaan, tetapi sekarang kami telah menghitung semua kelompok pesanan n (atau lebih baik, operasi di atasnya - tetapi set tetap, jadi itu adalah hal yang sama). Langkah selanjutnya: temukan isomorfisma. Isomorfisme adalah suatu ikatan antara dua kelompok tersebut sehingga φ (x ∗ y) = φ (x) ∗ φ (y) . Membuat bijections di CJam itu sepele:
Ne!
akan melakukannya. Bagaimana kita memeriksanya? Solusi saya mulai dari dua salinan tabel Cayley selama x ∗ y . Pada satu salinan, φ diterapkan ke semua elemen, tanpa menyentuh urutan baris atau kolom. Ini menghasilkan tabel untuk φ (x ∗ y) . Di sisi lain elemen dibiarkan apa adanya, tetapi baris dan kolom dipetakan melalui φ . Yaitu, baris / kolom x menjadi baris / kolomφ (x) . Ini menghasilkan tabel untuk φ (x) ∗ φ (y) . Sekarang kita memiliki dua tabel, kita hanya harus membandingkannya: jika mereka sama, kita telah menemukan isomorfisme.Tentu saja, kita juga perlu membuat pasangan kelompok untuk menguji isomorfisme. Kami membutuhkan semua 2 kombinasi grup. Sepertinya CJam tidak memiliki operator untuk kombinasi. Kita dapat menghasilkan mereka dengan mengambil setiap grup dan menggabungkannya hanya dengan elemen yang mengikutinya dalam daftar. Fakta menyenangkan: jumlah 2-kombinasi adalah n × (n - 1) / 2 , yang juga merupakan jumlah dari n - 1 bilangan asli. Angka tersebut disebut angka segitiga: coba algoritme di atas kertas, satu baris per elemen tetap, dan Anda akan tahu alasannya.
Kode di atas memperbaiki elemen pertama dari pasangan, L [X] , dan menggabungkannya dengan kelompok lain (sebut saja masing-masing dari mereka Y ). Ini melewati pasangan ke blok uji isomorfisma yang akan saya tunjukkan sebentar lagi. Blok memberikan kembali daftar nilai dari Y yang L [X] adalah isomorfik ke Y . Kemudian L [X] ditambahkan ke daftar ini. Sebelum memahami mengapa daftar diatur sedemikian rupa, mari kita lihat tes isomorfisme:
Hebat, sekarang kami memiliki daftar set seperti [{L [0], Y1, Y2, ...}, {L [1], Y1, ...}, ...] . Idenya di sini adalah, dengan properti transitif, jika ada dua set yang memiliki setidaknya satu elemen yang sama maka semua kelompok dalam dua set adalah isomorfik. Mereka dapat dikumpulkan menjadi satu set. Karena L [X] tidak akan pernah muncul dalam kombinasi yang dihasilkan oleh L [X + ...] , setelah menggabungkan setiap rangkaian isomorfisma akan memiliki satu elemen unik. Jadi, untuk mendapatkan jumlah isomorfisma, cukup untuk menghitung berapa banyak kelompok yang muncul tepat sekali dalam semua kelompok kelompok isomorfik. Untuk melakukan ini, saya membuka bungkusan set sehingga terlihat seperti [L [0], Y1, Y2, ..., L [1], Y1, ...] , urutkan daftar untuk membuat kelompok dari kelompok yang sama dan akhirnya RLE-encode itu.
Itu saja, semuanya.
sumber
CJam, 73 byte
Kompleksitas waktu dari kode di atas lebih buruk daripada O (n! N ) .
Input n = 4 sudah terlalu banyak untuk penerjemah online .
Menggunakan penerjemah Java , input n = 5 dapat dimungkinkan, jika Anda memiliki cukup RAM dan kesabaran.
Menemukan kelompok
Diberikan grup (G, ∗) dari pesanan n , kita dapat memilih penambangan acak φ: G -> C n sedemikian rupa sehingga φ (e) = 0 .
φ akan menjadi isomorfisma (G, ∗) dan (C n , ∗ ') jika kita mendefinisikan ∗' oleh x ∗ 'y = φ (φ -1 (x) ∗ φ -1 (y)) .
Ini berarti bahwa cukup untuk mempelajari semua operator grup dalam C n sehingga 0 adalah elemen netral.
Kami akan mewakili operator grup ∗ di C n dengan array T persegi panjang dimensi n × n sehingga T [x] [y] = x ∗ y .
Untuk menghasilkan sebuah array, kita bisa mulai dengan memilih permutasi dari C n untuk masing-masing nya n baris.
Dengan cara ini, 0 akan ada di semua baris (tetapi tidak harus semua kolom ), yang berarti bahwa kondisi ketiga (keberadaan invers) akan terpenuhi, apa pun e .
Kita bisa memperbaiki e = 0 dengan mengharuskan bahwa yang pertama kolom dari T sama dengan C n . Secara khusus, kondisi kedua (keberadaan elemen netral) akan berlaku.
Untuk memverifikasi bahwa T sesuai dengan operator grup, yang perlu dilakukan hanyalah memverifikasi bahwa kondisi pertama (asosiatif) berlaku. Ini dapat dilakukan secara mendalam dengan memeriksa bahwa T [T [x] [y]] [z] == T [x] [T [y] [z]] untuk semua x, y, z dalam C n .
Menghitung kelompok non-isomorfik
Metode di atas untuk menemukan kelompok akan menghasilkan beberapa kelompok isomorfik. Daripada mengidentifikasi mana yang isomorfik, kami menghasilkan keluarga semua kelompok isomorfik untuk masing-masing dari mereka.
Hal ini dapat dilakukan dengan mengulangi semua biopsi ject : C n -> C n , dan menentukan array yang terkait T array , yang didefinisikan oleh T by [x] [y] = φ -1 (T [φ (x)] [φ (y )]) .
Yang tersisa untuk dilakukan adalah menghitung jumlah keluarga yang berbeda.
Apa yang dilakukan kode
sumber
Python 2 ,
515507 byteCobalah online!
Menggunakan kesetaraan antara jumlah subkelompok urutan non-isomorfikn dari Σn dan jumlah kelas ekivalensi isomorfik dari kelompok tatanan terbatas n .
Tautan ke versi verbose .
sumber
s
danG
masalah? Jika tidak, Anda bisa menggunakandef f(k,*s):...f(~-k,j,*s)...
dandef c(k,*G):...c(~-k,s,*G)....
.