Komposisi permutasi - produk grup


12

Dengan dua permutasi dalam bentuk siklus disjoint, output produk / komposisinya dalam bentuk siklus disjoint.

Q · P = (1 5) (2 4) · (1 2 4 3) = (1 4 3 5).

Untuk menemukan komposisi, konversi siklus terpisah menjadi permutasi dalam notasi dua baris. Setiap angka di bagian yang terpisah dari suatu siklus dipetakan ke nomor yang mengikutinya di bagian yang sama. Itu membungkus. Jadi 1 -> 5, 5 -> 1, 2 -> 4, 4 -> 2. Jika nomor tidak ditemukan 3 -> 3, maka dipetakan ke dirinya sendiri. Siklus saling lepas pertama juga bisa ditulis (1 5)(2 4)(3). Pemetaan ini dikonversikan menjadi dua baris, seperti demikian (perhatikan bahwa urutan P dan Q terbalik):

Wow, gambar ini sangat besar!

[T] he produk dari dua permutasi diperoleh dengan mengatur ulang kolom dari permutasi kedua (paling kiri) sehingga baris pertama identik dengan baris kedua dari permutasi pertama (paling kanan). Produk kemudian dapat ditulis sebagai baris pertama dari permutasi pertama di atas baris kedua dari permutasi kedua yang dimodifikasi.

masukkan deskripsi gambar di sini

Artikel Wikipedia


Aturan:

  • Input akan diberikan sebagai daftar daftar atau format serupa
  • Anda mungkin tidak mengambil sesuatu seperti (1 5)(2 4)seperti [5, 4, 3, 2, 1], sudah dalam bentuk dua-line (indeks pemetaan nilai)
  • Tidak semua angka harus muncul di setiap grup, jadi Anda bisa (1 5)·(1 2), menghasilkan (2 5 1).
  • Output Anda harus dapat digunakan sebagai input Anda.
  • Anda tidak perlu mendukung input dengan siklus kosong (1 5)·(). Yang sebaliknya akan diberikan sebagai (1 5)·(1)atau sesuatu yang setara.
  • Karena siklus membungkus, urutannya tidak masalah asalkan hasilnya benar.
  • Anda bisa mulai dari nol atau satu. Tidak masalah, karena hasilnya sama.
  • Jumlahnya bisa lebih besar dari 9.
  • Anda mungkin tidak memasukkan angka yang sama lebih dari sekali dalam output. Jadi [[1],[1]]tidak diijinkan.
  • Perhatikan bahwa operasi ini tidak komutatif ! Saya menempatkan Q di depan P, karena itulah yang dilakukan Wikipedia. Anda dapat memilih pesanan apa pun, tetapi tentukan yang mana jika berbeda.
  • Kode terpendek menang
  • Built-in diizinkan, tetapi jika Anda menggunakannya, tunjukkan solusi tanpa menggunakannya juga.

Contoh:

Tidak semua kemungkinan output setara ditampilkan

Input
Output

[[1, 5], [2, 4]], [[1, 2, 4, 3]]
[[1, 4, 3, 5]] (or [[4, 3, 5, 1]] or ...)

[[1, 5]], [[1, 2]]
[[2, 5, 1]]

[[10, 2, 3]], [[2]]
[[3, 10, 2]]

[[1]], [[3]]
[[]] (or [[1]] or something equivalent)

[[10,2,3,15],[1,7],[5,6],[14,4,13,11,12]], [[5,6,7,9,14],[2,8,3,10],[1,11]]
[[12, 14, 6, 1], [8, 15, 10, 3, 2], [13, 11, 7, 9, 4]]

(arguments in reverse order from above gives a different answer)
[[5,6,7,9,14],[2,8,3,10],[1,11]], [[10,2,3,15],[1,7],[5,6],[14,4,13,11,12]]
[[9, 14, 4, 13, 1], [10, 8, 3, 15, 2], [7, 11, 12, 5]]

Bagi saya, ini adalah permutasi , bukan grup permutasi . Grup permutasi adalah kumpulan, ditutup di bawah operasi komposisi ini, dari sekelompok permutasi individu.
Greg Martin

@GregMartin Terminologi tetap
mbomb007

Jawaban:


2

J , 7 byte

C.@C.@,

Cobalah online!


Output Anda harus dapat digunakan sebagai input Anda.
mbomb007

@ mbomb007 Outputnya dapat digunakan sebagai input. Setiap daftar siklus harus berupa array berindeks 0 yang diindeks.
mil

Atau apakah ini perilaku cetak default J? Saya hanya ingin memastikan fungsinya bisa dirantai.
mbomb007

@ mbomb007 Ya itu hanya representasi visualnya. Itu harus 0-diindeks, tetapi saya memilikinya terdaftar sebagai 1-diindeks dan mengubahnya menjadi 0-indeks sebelum mereka disimpan dalam variabel yang akan diteruskan ke fungsi. Kemudian setelah itu, saya mengubahnya kembali dari 0-diindeks menjadi 1-diindeks sebelum mengeluarkannya.
mil

3

Mathematica, 15 byte

##⊙Cycles@{}&

Ya Virginia, ada builtin .... Mathematica mendukung tipe data permutasi yang sudah dalam notasi siklus terpisah: fungsi murni ini mengambil sebagai input sejumlah argumen dalam bentuk Cycles[{{1, 5}, {2, 4}}]dan output permutasi produk, lagi dalam Cycles[]bentuk. Ini menggunakan konvensi pemesanan yang berlawanan sebagai OP, jadi misalnya,

##⊙Cycles@{}&[Cycles[{{1, 2, 4, 3}}], Cycles[{{1, 5}, {2, 4}}]]

kembali Cycles[{{1, 4, 3, 5}}]. The simbol saya gunakan di atas harus benar-benar menjadi 3-byte swasta penggunaan Unicode simbol U + F3DE untuk bekerja di Mathematica. Perhatikan bahwa Mathematica memiliki builtin bernama untuk operasi ini PermutationProduct, tetapi itu tiga byte lebih lama.


3

Haskell , 157 148 byte

EDIT:

  • -9 byte: Itu memang bisa golf lebih banyak. Menghapus tanda kurung yang berlebihan di sekitar p++q. Urutan argumen bertukar g. Dihilangkan ddengan memulai iteratedengan p x, setelah itu takeWhiletidak lagi diikat dengan fst+ span. Dibuat iterateinfiks.

Melakukan ini ketika saya terlambat ... mungkin bisa bermain golf lagi.

Itu lebih sederhana, dan tampaknya diizinkan, sehingga output mencakup siklus elemen tunggal.

q#p=g(p++q>>=id)$f q.f p
f p a=last$a:[y|c<-p,(x,y)<-zip(0:c)(c++c),x==a]
g(x:l)p|c<-x:fst(span(/=x)$p`iterate`p x)=c:g[x|x<-l,x`notElem`c]p
g[]p=[]

Cobalah online!

Bagaimana itu bekerja:

  • #adalah fungsi utama. q#pmengambil dua daftar daftar angka, dan mengembalikan daftar serupa. Tes tampaknya memiliki Q sebelum P jadi saya menggunakan urutan yang sama.
  • f pmengubah permutasi pdari bentuk siklus disjoint ke fungsi, setelah itu f qdan f pdapat disusun dengan operator komposisi biasa ..
    • Pemahaman daftar iterasi melalui siklus c, mencari adan menemukan penggantinya. Jika pemahaman tidak menemukan apa pun, abaru dikembalikan.
    • zip(0:c)(c++c)adalah daftar pasangan elemen cdan penerusnya. Karena pertanyaannya memungkinkan kita "mulai pada satu" kita dapat menggunakan 0sebagai nilai dummy; lebih murah untuk menambahkannya ke zipargumen pertama daripada menggunakan argumen tailkedua.
  • g l pmengambil daftar lelemen, dan fungsi permutasi p, dan mengembalikan daftar siklus yang menyentuh elemen.
    • Ini cadalah siklus yang mengandung elemen pertama xdari daftar, elemen-elemen lain cditemukan dengan iterasi dari p xhingga xditemukan kembali. Ketika berulang-ulang untuk menemukan siklus yang tersisa, semua elemen cpertama dihapus dengan pemahaman daftar.

Terima kasih telah mencatat bahwa pesanan penting saat menghitung hasilnya. Saya lupa menambahkan contoh atau komentar tentang hal itu. Itu telah diperbaiki.
mbomb007

1

Python, 220 byte

a,b=eval(input())
p,o=a+b,[]
for i in range(1,1+max(map(max,p))):
 if not any(i in t for t in o):
  u,m=(i,),i
  while 1:
   for t in p[::-1]:
    if m in t:m=t[(t.index(m)+1)%len(t)]
   if m==i:o+=[u];break
   u+=(m,)
o

2
Selamat datang di situs ini. Saya melihat beberapa cara Anda dapat mempersingkat ini. Coba periksa halaman tips untuk python .
Ad Hoc Garf Hunter

0

Python 3.8 , 187 byte

q,p=eval(input())
g=lambda p,i:[*(c[c.index(i)-1]for c in p if i in c),i][0]
h=lambda*c:(x:=g(p,g(q,c[0])))in c and(*c[(m:=c.index(min(c))):],*c[:m])or h(x,*c)
exit({*map(h,sum(p|q,()))})

Cobalah online! atau Periksa semua test case!

Input : qdan pdalam urutan itu, masing-masing adalah satu set tupel, dari STDIN.
Output : Permutasi produk Q·Psebagai satu set tupel, untuk STDERR.

Penjelasan

Fungsi gmenemukan nomor mana yang memetakan ke nomor idalam permutasi p(alias gadalah permutasi terbalik p).

g=lambda p,i:        
[                   # creates a list
  *(                # containing the following
    c[c.index(i)-1] #   the number before i in cycle c
    for c in p      #   for all cycles in permutation
    if i in c       #   if i is in that cycle
  )                 #
  ,i                # adds i to the end of that list
                    #   (in case i is not in any cycle)
][0]                # returns the first element of the list

Fungsi hmengambil angka, dan mengembalikan siklus Q·Pyang berisi angka itu. Siklus yang dikembalikan akan menjadi tupel, diformat sedemikian rupa sehingga elemen terkecil berada di indeks 0.

h=lambda*c:                   # input: an incomplete cycle c, as a list
(x:=g(p,g(q,c[0])))           # finds the number x before the first number in c
in c                          # if x is also in c (aka the cycle is complete)
and                           # then returns the following:
(                             #   c as a tuple with min element at index 0
  *c[(m:=c.index(min(c))):],  #   (c, from the min element to the end)
  *c[:m]                      #   (c, from start to the min element)
)
or                            # else (cycle is incomplete) returns the following
h(x,*c)                       #   recursive result when after prepending x to c

Dengan menerapkan hke semua angka, kita bisa mendapatkan semua siklus Q·P. Untuk mencegah duplikat siklus dalam hasil kami, kami cukup menaruh semua siklus dalam satu set. Ini bekerja karena siklus serupa yang dikembalikan oleh hakan diformat ke tuple yang sama (dengan elemen terkecil pada indeks 0).
Kita hanya perlu mempertimbangkan angka yang muncul di Patau Q, karena semua nomor lain akan dipetakan ke diri mereka sendiri.

exit(              # returns through STDERR
  {                # create a set from the followings
    *map(h,        #   map function h to
      sum(p|q,())  #   all numbers in P or Q
    )
  }
)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.