Paritas Permutasi

14

Latar Belakang

The paritas permutasi , seperti yang didefinisikan oleh wikipedia , adalah sebagai berikut:

Tanda atau tanda tangan permutasi σ dilambangkan dengan sgn (σ) dan didefinisikan sebagai +1 jika σ genap dan −1 jika σ ganjil.

Tanda permutasi dapat secara eksplisit dinyatakan sebagai

sgn (σ) = (−1) ^ N (σ)

di mana N (σ) adalah jumlah inversi dalam σ.

Atau, tanda permutasi σ dapat didefinisikan dari dekomposisi menjadi produk transposisi sebagai

sgn (σ) = (−1) ^ m

di mana m adalah jumlah transposisi dalam dekomposisi.

Bagi Anda yang tidak suka sup alfabet Yunani dalam matematika mereka, saya akan mencoba dan menyederhanakan definisi sedikit dengan contoh (juga dicuri dari wikipedia).

Contoh

Pertimbangkan array input {1, 2, 3, 4, 5}, dan permutasi, katakanlah {3, 4, 5, 2, 1},. Untuk mendapatkan dari array asli ke permutasi, Anda harus bertukar indeks 0dan 2, 1dan 3, lalu 2dan 4. Meskipun ini bukan solusi yang unik, paritasnya didefinisikan dengan baik sehingga ini bekerja untuk semua kasus.

Karena membutuhkan 3 swap, kami memberi label permutasi ini dengan oddparitas. Seperti yang mungkin Anda harapkan, permutasi yang membutuhkan swap bahkan genap dikatakan memiliki evenparitas.

Tantangan

Tantangan Anda adalah menulis sebuah program sesedikit mungkin byte untuk menentukan paritas permutasi. Program atau fungsi Anda harus:

  • Terima sebagai argumen, dua larik input (atau string) mewakili satu set sebelum dan sesudah permutasi.
  • Kembalikan atau cetak karakter euntuk genap atau oganjil, diberi permutasi.
  • Harus mengasumsikan bahwa semua indeks dalam array atau string memiliki nilai unik.

Uji Kasus

Dengan asumsi Anda mendeklarasikan fungsi bernama f:

f([10], [10]) == "e"
f([10, 30, 20], [30, 20, 10]) == "e"
f([10, 30, 20, 40], [30, 20, 40, 10]) == "o"

Ini adalah , program terpendek dalam byte yang menang!

Patrick Roberts
sumber
4
Orang tidak akan menyukai format output yang ketat. Bagaimana dengan kebenaran untuk genap dan palsu untuk aneh? (atau sebaliknya)
CalculatorFeline
Saya sebenarnya berharap untuk mempertahankan format output yang saya tentukan kecuali orang lain benar-benar terganggu olehnya. Edit tunggu, saya akan kompromi.
Patrick Roberts
@CatsAreFluffy apakah itu lebih baik?
Patrick Roberts
Yah, kurasa kita akan lihat!
CalculatorFeline
Selamat malam! Berikut adalah beberapa saran untuk ketika Anda kembali ke ini (tapi tolong periksa sendiri): [10], [10] -> e(nol transposisi). [10 30 20], [30 20 10] -> e(dua transposisi). [10 30 20 40], [30 20 40 10] -> o(tiga transposisi)
Luis Mendo

Jawaban:

5

Jelly, 13 12 byte

żṗ2</€⁺Sị“oe

Cobalah online!

Bagaimana itu bekerja

żṗ2</€⁺Sị“oe  Main link. Arguments: A, B (lists)

ż             Zip A with B. Yields an array of pairs [x, σ(x)].
 ṗ2           Generate all pairs [[x, σ(x)], [y, σ(y)]].
   </€        Reduce each pair by </€.
              This maps [[x, σ(x)], [y, σ(y)]] to [x < y, σ(x) < σ(y)].
      ⁺       Repeat the previous link, i.e., execute </€ once more.
              This maps [x < y, σ(x) < σ(y)] to ((x < y) < (σ(x) < σ(y))), which is
              true if and only if x > y and σ(x) < σ(y).
       S      Sum. This counts the number of inversions.
        ị“oe  Retrieve the letter at the corresponding index.
              Indexing is 1-based and modular, so an odd sum retrieves the first
              letter, an even sum the second.
Dennis
sumber
1
Itu sangat kecil. Pujian!
Patrick Roberts
6

MATL , 17 16 byte

1 byte dihapus berkat saran dari Dennis

2$St!<Rz2\'oe'w)

Ini berfungsi dalam versi bahasa saat ini (15.0.0) .

Cobalah online !

Penjelasan

Ini menggunakan definisi paritas dalam hal inversi. Inversi adalah sepasang elemen dalam array kedua yang berada dalam urutan "salah" dibandingkan dengan array pertama. Karena array pertama tidak perlu disortir, pertama-tama kita mengurutkannya dan penataan ulang yang sama diperlukan untuk pengurutan yang diterapkan ke array kedua. Kemudian inversi berhubungan dengan sepasang elemen yang tidak meningkat dalam array kedua.

Perhatikan juga bahwa kedua array input dapat ditukar dan hasilnya adalah sama. Jadi tidak penting array mana yang dianggap sebagai "asli" dan yang "permutasi".

2$S     % implicitly take two row vectors. Sort second and apply the indices
        % of that sorting to the first
t!      % duplicate. Transpose into column vector
<       % true for elements of the column vector that exceed those of the 
        % row vector. Gives a 2D array with all pairs of comparisons
R       % keep only upper triangular part of that array
z       % number of nonzero elements. This is the number of inversions
2\      % parity of that number: gives 0 or 1
'oe'w   % push string 'eo' below the top of the stack
)       % apply index to produce 'e' or 'o'. An index 1 refers to the first
        % element, whereas 0 refers to the last. Implicitly display 
Luis Mendo
sumber
1
Ini adalah solusi yang sangat pintar!
Alex A.
@AlexA. Terima kasih! Saya telah mengedit jawaban untuk mengklarifikasi apa yang dilakukan bagian pemesanan sebelumnya: kami mengurutkan satu array dan kemudian pengaturan ulang yang sama diperlukan untuk pengurutan yang diterapkan ke array lainnya.
Luis Mendo
1
Anda harus menambahkan pengindeksan modular ke MATL. Itu akan menghemat 3 byte di sini.
Dennis
@ Dennis Ya, saya sering berpikir tentang itu ... tetapi saat ini menggunakan format di mana nilai negatif memiliki arti yang berbeda. Saya memilih itu untuk memiliki indeks formulir x(1:end-2)dll tanpa secara eksplisit menunjukkan ukuran x. Tidak yakin apakah itu pilihan yang baik, tapi saya kira sudah terlambat untuk berubah sekarang :-) Mungkin saya akan menemukan cara yang kompatibel untuk menambahkan pengindeksan modular
Luis Mendo
... dan indeks yang melebihi panjang saat ini digunakan untuk menetapkan nilai baru. Tetapi indeks 0memang memiliki arti "entri terakhir", jadi saya dapat menyimpan byte (menghapus kenaikan). Terima kasih atas idenya!
Luis Mendo
5

Oktaf, 56 52 byte

Tampaknya tidak ada yang menggunakan pendekatan ini sejauh ini: Pada dasarnya saya hanya menggunakan determinan dari matriks permutasi yang sesuai. Ekspresi det(eye(nnz(a))(a,:))mengembalikan penentu matriks permutasi yang didefinisikan oleh vektor a. Maka itu hanya masalah mengekstraksi karakter yang tepat dari string, tergantung pada hasilnya.

p=@(v)eye(nnz(v))(v,:);@(a,b)'ole'(det(p(a)*p(b))+2)
cacat
sumber
2
Ide bagus untuk menggunakan determinan. Ole!
Luis Mendo
5

Haskell, 58 byte

k%l|m<-zip k l=cycle"eo"!!sum[1|(a,b)<-m,(c,d)<-m,a<c,b>d]

Pemakaian:

*Main> [8,3,5]%[5,3,8]
'o'

Metode yang sama dengan jawaban Python saya . haskeller bangga menyimpan byte dengan cycle.

Tidak
sumber
1
Anda dapat menulis cycle"eo"!!...Alih-alih "eo"!!mod(...)2, menghemat satu byte.
haskeller bangga
4

Python 2, 68 byte

lambda*M:"eo"[sum(a<b<M>A>B for a,A in zip(*M)for b,B in zip(*M))%2]

Pemakaian:

>>> f=lambda*M:"eo"[sum(a<b<M>A>B for a,A in zip(*M)for b,B in zip(*M))%2]
>>> f([8,3,5],[5,3,8])
'o'

Menghitung jumlah pasangan inversi dari dua daftar yang di-zip, i, e. nilai (a,A)dan (b,B)dari setiap daftar pada indeks yang sama dengan a<bdan A>B. Perbandingan ini digabungkan sebagai a<b<M>A>B, menggunakan properti yang daftarnya Mlebih besar dari angka apa pun. Jumlahnya kemudian diambil modulo 2 dan diubah menjadi eatau o.

Tidak
sumber
3

JavaScript (ES6), 73 byte

(a,b)=>"eo"[r=0,g=a=>a.map((e,i)=>a.slice(i).map(d=>r^=d<e)),g(a),g(b),r]

Karena kami hanya tertarik pada paritas, transposisi duplikat hanya dibatalkan. Subskrip larik JavaScript yang nyaman bukan multidimensi.

Neil
sumber
1
Tempat menarik untuk koma .. tidak tahu Anda bisa melakukannya. Jangan lupa tentang currying untuk -1 byte
Patrick Roberts
2

Mathematica, 77 byte

If[Mod[Plus@@Length/@(Join[{0},#]&)/@PermutationCycles[#][[1]],2]==0,"e","o"]&

Saya setuju!

CalculatorFeline
sumber
Fungsi praktis, sayangnya nama panjang!
Patrick Roberts
Mengganggu, bukan? Saya benci Cycles. Itu menabrak ukuran PermutationCyclesnama, dan bahkan PermutationCyclesbodoh, mengembalikan Cyclesobjek! `
CalculatorFeline
2

Mathematica, 31 byte

If[Tr[Signature/@{##}]==0,o,e]&

Tanda tangan [daftar] memberikan tanda tangan permutasi yang diperlukan untuk menempatkan elemen-elemen daftar dalam urutan kanonik

Kami dapat memesan ulang satu daftar ke yang lain, dengan terlebih dahulu memesan kembali satu daftar ke urutan apa pun (dalam hal ini urutan kanonik) dan menyusun ulang daftar ini ke daftar akhir. Tanda dari permutasi keseluruhan adalah genap, jika tanda dari dua sub-permutasi adalah sama.

murphy
sumber