Помножте матриці Паулі


12

У матрицях Паулі є набором матриць 2х2 , які з'являються дуже часто в квантовій фізиці (немає, вам не потрібно знати ніякої квантову фізику для цього завдання). Якщо в набір включити ідентичність, чотирма матрицями є:

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

Множення двох з них завжди буде давати іншу матрицю Паулі, хоча це може бути помножена на один зі складних етапів 1, i, -1, -i. Так , наприклад, .σ1σ3 = -iσ2

Ваше завдання - множити ряд матриць Паулі та повернути отриману матрицю та фазу. Введення буде подано у вигляді непустого рядка цифр 0для 3подання матриць до . Вихід повинен бути рядок, що містить одну цифру для отриманої матриці, необов'язково передуючи їй , або для позначення фази ( є для ).σ0σ3i--i--1

Ви можете написати програму або функцію, взявши введення через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції та вивівши результат через STDOUT (або найближчу альтернативу), значення повернення функції або параметр функції (out).

Ви не повинні використовувати будь-які вбудовані (або сторонні) функції, пов’язані з матрицями Паулі.

Це кодовий гольф, найкоротша відповідь (у байтах) виграє.

Випробування

1 => 1
13 => -i2
000 => 0
123 => i0
03022 => 3
02132230 => -i3
1320130100032 => i2
311220321030322113103 => -2
0223202330203313021301011023230323 => -i0
1323130203022111323321112122313213130330103202032222223 => -1

3
Я додав тег абстрактно-алгебри, оскільки це, по суті, просить спростити слова в узагальненій групі кватерніонів .
Пітер Тейлор

Відповіді:


3

Pyth, 47 байт

Я здогадуюсь, це все ще гольфа. Але це сильно б'є CJam.

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

Спробуйте в Інтернеті: Демонстрація або Тестовий набір

Пояснення

Визначити отриманий тип матриці - просто збити всі числа.

Під час множення 2 матриць A*Bфаза змінюється, якщо не з матриць є σ0і 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

звичайно, у мене 44, якщо я використовую той же алгоритм, який по суті є Sp300.
Оптимізатор

9

Python 2, 108 89 87 86 байт

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`

(Дякую @grc та @xnor за допомогу)

Пояснення

Давайте розділимо коефіцієнт і базову матрицю. Якщо ми зосередимося на базову матриці тільки ми отримаємо цю таблицю множення (наприклад , 13є -i2, тому ми поміщаємо 2):

  0123

0 0123
1 1032
2 2301
3 3210

що, як буває, те саме, що робити побіжно xor.

Тепер зупинимось на коефіцієнтах. Якщо дозволити 0123позначати 1,i,-1,-iвідповідно, отримаємо:

  0123

0 0000
1 0031
2 0103
3 0310

Для цього ми спочатку перевіряємо, чи будь-яке число дорівнює 0 m*y, дотримуючись лівого стовпця та верхнього рядка. (m-y)%3Потім додавання дає:

  0123

0 0000
1 0021
2 0102
3 0210

що близько, за винятком того, що ми маємо 2замість цього 3. Ми враховуємо це, виконуючи *3/2.

Для індексації ми помічаємо, що якщо ми беремо рядок "--i"і вибираємо кожен другий символ, починаючи з отриманих 0123нами індексів "-i","-","i","".


Гарна нарізка струни, я забув про це . Я вірю, що ти можеш зробити так, 3-n%4як ~n%4. Я підозрюю, що ви можете висловити m*y and(m-y)%3*3/2коротше в чарівної струни, але моя перша спроба 877449216>>2*m+8*yлише зв'язалася. Існує також досить алгебраїчна формула, що якщо Y=m^y, вираз є (m-y)*(y-Y)*(Y-m)/2, але це довго.
xnor

@xnor О ~, приємно - неспокійний мене дратував: / Я впевнений, що і мене m*y and(m-y)%3*3/2можна скоротити, але я провів всю ніч і нікуди не дістався ... Я повернусь до цього, якщо я встигати. Можливо, факт, що у мене є свобода мода 4, може допомогти.
Sp3000

6

Сітківка , 77 байт

Я думав, що скористаюся цією можливістю, щоб показати нову функцію Retina: багатоступеневі петлі. Це повинно значно скоротити багато завдань (особливо умовну заміну).

ii
-
+`(.)\1|0

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

Retina - це моя власна мова програмування на основі регулярних виразів. Вихідний код можна згрупувати за етапами: кожен етап складається з двох рядків, де перший містить регулярний вираз (і, можливо, деяку конфігурацію), а другий рядок - рядок заміни. Потім етапи застосовуються до STDIN в порядку, і кінцевий результат друкується в STDOUT.

Ви можете використовувати вищезазначене безпосередньо як вихідний файл за -sдопомогою перемикача командного рядка. Однак я не рахую комутатор, тому що ви також можете просто помістити кожен рядок в окремий файл (тоді ви втрачаєте 15 байт для нових рядків, але додаєте +15 для додаткових файлів).

Пояснення

Нове в цьому рішенні - )передостанній етап. Це закриває багатоступеневу петлю. Немає відповідності (, а це означає, що цикл неявно починається на першому етапі. Отже, перші 7 етапів повторюються, поки повний прохід через усі 7 з них не перестане змінювати результат. Ці 7 етапів просто виконують різні перетворення, які поступово зменшують кількість матриць у рядку та поєднують фази. Як тільки ми досягнемо остаточного результату, жоден із семи шаблонів більше не відповідає, і цикл закінчується. Після цього ми додаємо 0, якщо в результаті ще немає цифри (оскільки на вищезазначених етапах просто випадають усі тотожності, включаючи результат).

Ось що роблять окремі етапи:

ii
-

Поєднує всі пари iв, -щоб зменшити символи фази.

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

Тепер, якщо залишилося два послідовних однакових символа, це одна --чи дві однакові матриці. У будь-якому випадку множення їх дає тотожність. Але нам не потрібні ідентичності, тому ми просто видаляємо їх усі, а також явні ідентичності 0. Цей етап повторюється сам по собі, +поки результат не перестане змінюватися. Це гарантує, що такі речі, як 123321вирішити, повністю, так що наступним кроком можна вважати, що всі пари цифр є різними.

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

Це насправді дві окремі трансформації в одну (для гольфу). Зверніть увагу, що якщо перші альтернативні збіги, $2і $3порожні, а якщо другі збіги $1порожні. Отже, це можна розкласти на два етапи:

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

Це просто замінює всі пари цифр і додає знак мінус. Так як ми видалили всі 0з і всі однакові пари, то це буде відповідати тільки 12, 23, 31, 21, 32, 13. Цей крок може здатися дивним, але він дозволяє мені перевірити лише половину цих випадків пізніше, тому що ті, які я не можу обробити, будуть замінені тут у наступній ітерації.

Інша частина вищезгаданого етапу була:

(.)-
-$1

Це поступово пересуває -знаки повністю вліво (по одному положенню за ітерацію). Я роблю це так, що в кінцевому рахунку вони всі поруч і вирішуються на попередньому кроці.

12
i3
23
i1
31
i2

Ці три етапи тепер просто вирішують три пари продуктів. Як я вже говорив вище, це охопить лише половину відповідних випадків, але інша половина буде опікуватися в наступній ітерації, після попереднього кроку замінено всі пари.

)`(\d)i
i$1

Це останній етап циклу. Він схожий на той, що зміщується -вліво, за винятком i. Основна відмінність полягає в тому, що цей обмінюється iлише цифрами. Якби я використовував (.)iтоді, у випадках, коли я отримав -iабо i-два, було б замінено на невизначений час, і програма не припиниться. Тож це лише замінює їх праворуч від -знаків. Цього достатньо - доки всі -і iз’являться разом у якийсь момент, їх можна правильно вирішити.

^\D*$
$&0

Заключний крок (поза петлею). Пам’ятайте, що ми завжди видаляли всі ідентичності, тому, якщо результатом є фактично ідентичність (раз фаза), тоді ми більше не матимемо потрібної цифри у висновку, тому додаємо її назад.

Як приклад, ось усі проміжні форми 0223202330203313021301011023230323(пропускні етапи, які не виконують жодних змін):

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.