Gandakan Matriks Pauli

12

The matriks Pauli adalah seperangkat 2x2 matriks yang muncul sangat umum di fisika kuantum (tidak ada, Anda tidak perlu tahu apa fisika kuantum untuk tantangan ini). Jika kita memasukkan identitas dalam set, empat matriks adalah:

 σ0 =      σ1 =      σ2 =      σ3 = 
[1  0]    [0  1]    [0 -i]    [1  0]
[0  1]    [1  0]    [i  0]    [0 -1]

Mengalikan dua ini akan selalu memberikan matriks Pauli lain, meskipun mungkin dikalikan dengan salah satu tahapan yang kompleks 1, i, -1, -i. Misalnya ,.σ1σ3 = -iσ2

Tugas Anda adalah melipatgandakan sejumlah matriks Pauli dan mengembalikan matriks dan fase yang dihasilkan. Masukan akan diberikan sebagai string yang tidak kosong digit 0untuk 3mewakili matriks untuk . Output harus berupa string yang berisi satu digit untuk matriks yang dihasilkan, secara opsional didahului oleh , atau untuk menunjukkan fase ( untuk ).σ0σ3i--i--1

Anda dapat menulis suatu program atau fungsi, mengambil input melalui STDIN (atau alternatif terdekat), argumen baris perintah atau argumen fungsi dan mengeluarkan hasilnya melalui STDOUT (atau alternatif terdekat), nilai pengembalian fungsi atau parameter fungsi (keluar).

Anda tidak boleh menggunakan fitur bawaan (atau pihak ketiga) yang terkait dengan matriks Pauli.

Ini kode golf, jawaban terpendek (dalam byte) menang.

Uji Kasus

1 => 1
13 => -i2
000 => 0
123 => i0
03022 => 3
02132230 => -i3
1320130100032 => i2
311220321030322113103 => -2
0223202330203313021301011023230323 => -i0
1323130203022111323321112122313213130330103202032222223 => -1
Martin Ender
sumber
3
Saya telah menambahkan tag aljabar abstrak karena ini pada dasarnya meminta penyederhanaan kata-kata dalam grup angka empat umum .
Peter Taylor

Jawaban:

3

Pyth, 47 byte

Saya kira ini masih golf. Tapi itu mengalahkan CJam banyak.

p.U&-=T*q3l{[0bZ)^_1%-Zb3xbZmvdz@+c"i - -i")khT

Cobalah online: Demonstrasi atau Test Suite

Penjelasan

Menentukan jenis matriks yang dihasilkan cukup dengan memasukkan semua angka.

Sementara mengalikan 2 matriks A*B, fase berubah, jika bukan dari matriks adalah σ0dan A != B.

                                                 implicit: T=10, z=input string
                            mvdz                 evaluate each char of the input 
 .U                                              reduce: b=first value, for Y in mvdz[1:]
    -=T                                            T -= ...
        q3l{[0bZ)                                     (3 == len(set([0,b,Z])))
       *         ^_1%-Zb3                             * (-1)^((Z-b)%3)
   &                                               and
                         xbY                       update b by (b xor Y)
                                 +c"i - -i")k    the list ["i", "-", "-i", ""]
                                @            hT  take the element at index T+1 (modulo wrapping)
p                                                print phase and matrix
Jakube
sumber
tentu saja saya memiliki 44 jika saya menggunakan algoritma yang sama, yang pada dasarnya adalah Sp300.
Pengoptimal
9

Python 2, 108 89 87 86 byte

x=y=0
for m in map(int,raw_input()):x+=m*y and(m-y)%3*3/2;y^=m
print"--i"[~x%4::2]+`y`

(Terima kasih kepada @grc dan @xnor untuk bantuannya)

Penjelasan

Mari kita pisahkan koefisien dan matriks dasar. Jika kita fokus pada matriks dasar saja, kita mendapatkan tabel perkalian ini (misalnya 13adalah -i2, sehingga kami menempatkan 2):

  0123

0 0123
1 1032
2 2301
3 3210

yang kebetulan sama dengan melakukan bitwise xor.

Sekarang mari kita fokus pada koefisien. Jika kita membiarkan masing-masing 0123menunjukkan 1,i,-1,-i, kita mendapatkan:

  0123

0 0000
1 0031
2 0103
3 0310

Untuk ini, pertama-tama kita memeriksa apakah salah satu angka 0 dengan melakukan m*y, menjaga kolom kiri dan baris atas. Menambahkan (m-y)%3kemudian memberi:

  0123

0 0000
1 0021
2 0102
3 0210

yang dekat, kecuali bahwa kita memiliki 2bukan 3. Kami memperhitungkan ini dengan melakukan *3/2.

Untuk pengindeksan, kami perhatikan bahwa jika kami mengambil string "--i"dan memilih setiap karakter kedua mulai dari indeks yang 0123kami dapatkan "-i","-","i","".

Sp3000
sumber
Mengiris tali yang bagus, saya lupa tentang ini . Saya percaya Anda bisa melakukan 3-n%4seperti ~n%4. Saya menduga Anda dapat mengekspresikan m*y and(m-y)%3*3/2lebih pendek dalam string sihir, tetapi upaya pertama saya 877449216>>2*m+8*yhanya terikat. Ada juga formula aljabar yang cantik, kalau Y=m^yungkapannya begitu (m-y)*(y-Y)*(Y-m)/2, tapi itu panjang.
xnor
@ xnor Oh ~, bagus - off-by-one itu mengganggu saya: / Saya cukup yakin m*y and(m-y)%3*3/2bisa dipersingkat juga, tapi saya menghabiskan sepanjang malam dan tidak mendapatkan tempat ... Saya akan kembali ke sana jika saya punya waktu. Mungkin fakta bahwa saya memiliki kebebasan mod 4 mungkin membantu.
Sp3000
6

Retina , 77 byte

Saya pikir saya akan menggunakan kesempatan ini untuk memamerkan fitur Retina baru: loop multi-tahap. Ini harus mempersingkat banyak tugas (terutama penggantian bersyarat).

ii
-
+`(.)\1|0

(.)-|(\d)(\d)
-$1$3$2
12
i3
23
i1
31
i2
)`(\d)i
i$1
^\D*$
$&0

Retina adalah bahasa pemrograman berbasis regex saya sendiri. Kode sumber dapat dikelompokkan menjadi beberapa tahap: setiap tahap terdiri dari dua baris di mana yang pertama berisi regex (dan berpotensi beberapa konfigurasi) dan baris kedua adalah string pengganti. Tahapan-tahapan tersebut kemudian diterapkan pada STDIN secara berurutan dan hasil akhirnya dicetak ke STDOUT.

Anda dapat menggunakan di atas secara langsung sebagai file sumber dengan -ssaklar baris perintah. Namun, saya tidak menghitung tombolnya, karena Anda juga bisa meletakkan setiap baris dalam file yang terpisah (maka Anda kehilangan 15 byte untuk baris baru, tetapi tambahkan +15 untuk file tambahan).

Penjelasan

Hal baru tentang solusi ini adalah )pada tahap kedua dari belakang. Ini menutup loop multi-tahap. Tidak ada yang cocok (, yang berarti bahwa loop secara implisit dimulai pada tahap pertama. Oleh karena itu, 7 tahap pertama diulangi sampai lulus penuh semua 7 dari mereka berhenti mengubah hasilnya. 7 tahap ini hanya melakukan berbagai transformasi yang secara bertahap mengurangi jumlah matriks dalam string dan menggabungkan fase. Setelah kami mencapai hasil akhir, tidak ada dari tujuh pola yang cocok lagi dan loop berakhir. Setelah itu, kami menambahkan 0 jika belum ada angka di hasilnya (karena tahap di atas cukup lepaskan semua identitas, termasuk hasilnya).

Inilah yang dilakukan masing-masing tahapan:

ii
-

Menggabungkan semua pasangan ike dalam -untuk mengurangi karakter fase.

+`(.)\1|0
<empty>

Sekarang jika ada dua karakter identik berturut-turut yang tersisa, itu salah satu --atau dua matriks identik. Dalam kedua kasus itu, mengalikannya memberi identitas. Tapi kami tidak membutuhkan identitas, jadi kami hanya menghapus semuanya, dan identitas eksplisit 0juga. Tahap ini diulang dengan sendirinya +sampai hasilnya berhenti berubah. Ini memastikan bahwa hal-hal seperti 123321diselesaikan sepenuhnya, sehingga langkah selanjutnya dapat mengasumsikan bahwa semua pasangan digit berbeda.

(.)-|(\d)(\d)
-$1$3$2

Ini sebenarnya dua transformasi terpisah dalam satu (untuk golfitude). Perhatikan bahwa jika alternatif pertama cocok, $2dan $3kosong, dan jika yang kedua cocok, $1kosong. Jadi ini dapat diuraikan menjadi dua langkah ini:

(\d)(\d)
-$2$1

Ini hanya menukar semua pasangan digit dan menambahkan tanda minus. Karena kita dihapus semua 0dan semua pasangan identik, ini hanya akan cocok 12, 23, 31, 21, 32, 13. Langkah ini mungkin tampak aneh, tetapi ini memungkinkan saya untuk hanya memeriksa setengah dari kasus-kasus ini nanti, karena yang saya tidak bisa proses kemudian akan ditukar di sini di iterasi berikutnya.

Bagian lain dari tahap di atas adalah:

(.)-
-$1

Ini secara bertahap memindahkan -tanda-tanda sampai ke kiri (satu posisi per iterasi). Saya melakukan ini sehingga pada akhirnya mereka semua bersebelahan dan diselesaikan pada langkah sebelumnya.

12
i3
23
i1
31
i2

Tiga tahap ini sekarang hanya menyelesaikan tiga pasang produk. Seperti yang saya katakan di atas, ini hanya akan menangkap setengah dari kasus yang relevan, tetapi setengah lainnya akan diurus dalam iterasi berikutnya, setelah langkah sebelumnya bertukar semua pasangan.

)`(\d)i
i$1

Ini adalah tahap terakhir dari loop. Ini mirip dengan yang bergeser -ke kiri, kecuali untuk i. Perbedaan utama adalah bahwa ini ihanya bertukar dengan angka. Jika saya menggunakan (.)imaka dalam kasus di mana saya mendapatkan -iatau i-keduanya akan ditukar tanpa batas waktu dan program tidak akan berakhir. Jadi ini hanya menukar mereka ke kanan -tanda. Ini cukup - selama semua -dan imuncul bersama di beberapa titik, mereka dapat diselesaikan dengan benar.

^\D*$
$&0

Langkah terakhir (di luar loop). Ingat bahwa kami selalu menghapus semua identitas, jadi jika hasilnya sebenarnya adalah identitas (kali fase), maka kami tidak akan memiliki angka yang diperlukan dalam output lagi, jadi kami menambahkannya kembali.

Sebagai contoh, berikut adalah semua bentuk peralihan 0223202330203313021301011023230323(melewatkan tahapan yang tidak melakukan perubahan apa pun):

0223202330203313021301011023230323

321321312        # Remove identities
-23-31-12-132    # Swap all pairs
-23-31-i3-132    # Resolve 12
-i1-31-i3-132    # Resolve 23
-i1-i2-i3-132    # Resolve 31
-i-1i-2i-3-312   # Move - to the left and swap pairs
-i-1i-2i-3-3i3   # Resolve 12
-i-i1-i2-3-i33   # Move i to the left
-i-i1-i2-3-i     # Remove identities
--ii-1i-2-3i     # Move - to the left
--ii-i1-2-i3     # Move i to the left
----i1-2-i3      # Resolve ii
i1-2-i3          # Remove identities
i-1-2i3          # Move - to the left
i-1-i23          # Move i to the left
-i-1i-32         # Move - to the left and swap pairs
-i-i1-32         # Move i to the left
--ii-1-23        # Move - to the left and swap pairs
--ii-1-i1        # Resolve 23
----1-i1         # Resolve ii
1-i1             # Remove identities
-1i1             # Move - to the left
-i11             # Move i to the left
-i               # Remove identities. Now the loop can't change this any longer.
-i0              # Fix the result by adding in the 0.
Martin Ender
sumber