Створіть матрицю Уолша


22

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

Властивості матриць Уолша

Розміри такі ж , сили 2. Таким чином, ми можемо звернутися до цих матрицях до два експонента тут, називаючи їх W(0), W(1), W(2)...

W(0)визначається як [[1]].

Для n>0, W(n)виглядає наступним чином :

[[W(n-1)  W(n-1)]
 [W(n-1) -W(n-1)]]

Так і W(1)є:

[[1  1]
 [1 -1]]

І W(2)це:

[[1  1  1  1]
 [1 -1  1 -1]
 [1  1 -1 -1]
 [1 -1 -1  1]]

Шаблон продовжується ...

Ваше завдання

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

Стандартні лазівки заборонені.

Кілька речей:

Для W(0), то 1потрібно не бути обгорнуті навіть один раз. Це може бути просто ціле число.

Вам дозволено 1-індексні результати W(1)- тоді б це було [[1]].

Тестові кейси

0 -> [[1]]
1 -> [[1  1]
      [1 -1]]
2 -> [[1  1  1  1]
      [1 -1  1 -1]
      [1  1 -1 -1]
      [1 -1 -1  1]]
3 -> [[1  1  1  1  1  1  1  1]
      [1 -1  1 -1  1 -1  1 -1]
      [1  1 -1 -1  1  1 -1 -1]
      [1 -1 -1  1  1 -1 -1  1]
      [1  1  1  1 -1 -1 -1 -1]
      [1 -1  1 -1 -1  1 -1  1]
      [1  1 -1 -1 -1 -1  1  1]
      [1 -1 -1  1 -1  1  1 -1]]

8 -> Пастебін

Це , тому найкоротше рішення на кожній мові виграє! Щасливого гольфу!



Чи можуть бути результати 1-індексованими? (наприклад, W(1)повертається [[1]], W(2)повертається [[1,1],[1,-1]...)
Лев

@Leo Так, вони можуть. Відредаговано в.
Хулдразес на’Барія

Відповіді:



10

MATL , 4 байти

W4YL

Спробуйте в Інтернеті!

Як це працює:

W       % Push 2 raised to (implicit) input
4YL     % (Walsh-)Hadamard matrix of that size. Display (implicit)

Без вбудованого: 11 байт

1i:"th1M_hv

Спробуйте в Інтернеті!

Як це працює :

Для кожної матриці Уолша W наступна матриця обчислюється як [ W W ; W - W ], як описано в виклику. Код це робить так n, починаючи з матриці 1 × 1 [1].

1       % Push 1. This is equivalent to the 1×1 matrix [1]
i:"     % Input n. Do the following n times
  t     %   Duplicate
  h     %   Concatenate horizontally
  1M    %   Push the inputs of the latest function call
  _     %   Negate
  h     %   Concatenate horizontally
  v     %   Concatenate vertically
        % End (implicit). Display (implicit)

2
Тьфу ... і ось я це намагаюся використовувати kron. ;)
стаканчик


5

Октава з вбудованим, 18 17 байт

@(x)hadamard(2^x)

Спробуйте в Інтернеті!

Октава без вбудованих, 56 51 47 байт

function r=f(x)r=1;if x,r=[x=f(x-1) x;x -x];end

Спробуйте в Інтернеті! Завдяки @Luis Mendo за -4.

Октава з рекурсивною лямбда, 54 53 52 48 байт

f(f=@(f)@(x){@()[x=f(f)(x-1) x;x -x],1}{1+~x}())

Спробуйте в Інтернеті! Завдяки цій відповіді та цьому питанню для натхнення.


Якщо функція визначена у файлі, друга endне потрібна. Таким чином, ви можете перемістити його до заголовка TIO і таким чином видалити його з підрахунку байтів
Луїс Мендо


4

Python 2 , 75 71 байт

r=range(2**input())
print[[int(bin(x&y),13)%2or-1for x in r]for y in r]

Спробуйте в Інтернеті!

Матриця Уолша, схоже, пов'язана із злими числами. Якщо x&y(побітовое і координат 0 на основі) являє собою число зла, значення в матриці 1, -1для одіозних чисел. Розрахунок паритету бітів int(bin(n),13)%2взято з коментаря Noodle9 до цієї відповіді .


2
Інтуїтивно, знак у (x, y) перевертається стільки разів, скільки є рівні рекурсії, на яких (x, y) знаходиться в правому нижньому квадранті матриці (2 ^ k × 2 ^ k), яка виникає коли x і y обидва мають k в k-му біті. Використовуючи цей факт, ми можемо просто порахувати 1 біт, x&yщоб визначити, скільки разів перевернути знак.
Лінн

4

R , 61 56 53 50 байт

w=function(n)"if"(n,w(n-1)%x%matrix(1-2*!3:0,2),1)

Спробуйте в Інтернеті!

Рекурсивно обчислює матрицю за продуктом Kronecker і повертає 1 на n=0випадок (завдяки Джузеппе за вказівку на це, а також JAD за те, що він допомагав гольфу в початковій версії).

Додаткові -3 байти знову завдяки Джузеппе.


Данно, якщо повернення, 1а не matrix(1)дійсне, але якщо це так, ви можете пограти вниз, і є також 61 байтний Reduceпідхід: спробуйте!
Джузеппе

Я також не впевнений у форматі n=0випадку, більшість інших відповідей містять його в [[1]], але не у всіх ...
Кирилл Л.

1
Ви можете замінити matrix(1)на t(1).
JAD

1
Питання відредаговано. Ви можете повернути ціле число, а не матрицю.
Khuldraeseth na'Barya

1
1-2*!3:0коротше, ніж c(1,1,1,-1)на три байти.
Джузеппе


2

JavaScript (ES6), 77 байт

n=>[...Array(1<<n)].map((_,i,a)=>a.map((_,j)=>1|-f(i&j)),f=n=>n&&n%2^f(n>>1))

Наївний розрахунок починається з прийняття 0 <= X, Y <= 2**Nв W[N]. Простий випадок - це колиX або Yменше, ніж 2**(N-1)в такому випадку, ми повторюємо повтор на X%2**(N-1)і Y%2**(N-1). У випадку обох Xі Yщонайменше2**(N-1) рекурсивного виклику потрібно заперечувати.

Якщо замість того, щоб порівнювати Xчи Yменше, ніж 2**(N-1)бітмаска X&Y&2**(N-1), то це не нульове значення, коли рекурсивний виклик потрібно заперечувати, і нульове, коли його немає. Це також дозволяє уникнути необхідності зменшення модуля 2**(N-1).

Зрозуміло, біти можна перевірити в зворотному порядку для того ж результату. Тоді замість того, щоб подвоювати бітову маску щоразу, коли ми координуємо її, можна замінити вдвічі, що дозволяє результатам XORed, внаслідок чого кінцевий результат 0означає відсутність заперечення і1 означає заперечення.



2

Гм, чому перекладач не на GitHub?
Ерік Аутгольфер

@EriktheOutgolfer Я волію не публікувати код занадто широко в цей час.
ngn

Гм, то як ти додав його до TIO?
Ерік Аутгольфер

@EriktheOutgolfer Я ввічливо запитав :) У TIO є інші власні мови - Mathematica, Dyalog.
ngn

1

05AB1E , 16 байт

oFoL<N&b0м€g®smˆ

Спробуйте в Інтернеті!

Пояснення

oF                 # for N in 2**input do:
  oL<              # push range [1..2**input]-1
     N&            # bitwise AND with N
       b           # convert to binary
        0м         # remove zeroes
          €g       # length of each
            ®sm    # raise -1 to the power of each
               ˆ   # add to global array

Мені б хотілося, щоб я знав коротший спосіб обчислення ваги Хеммінга.
1δ¢˜така ж довжина, як і 0м€g.


1

Лушпиння , 13 байт

!¡§z+DS+†_;;1

Спробуйте в Інтернеті!

1-індексований.

Пояснення

!¡§z+DS+†_;;1
 ¡        ;;1    Iterate the following function starting from the matrix [[1]]
  §z+              Concatenate horizontally
     D               The matrix with its lines doubled
      S+†_           and the matrix concatenated vertically with its negation
!                Finally, return the result after as many iterations as specified
                 by the input (where the original matrix [[1]] is at index 1)



0

Python 2 , 49 байт

Показано пару підходів за допомогою додаткових бібліотек. Це спирається на вбудований в Scipy:

lambda n:hadamard(2**n)
from scipy.linalg import*

Спробуйте в Інтернеті!

Python 2 , 65 байт

А цей використовує лише Numpy і вирішує продукт Kronecker, аналогічно моїй відповіді R :

from numpy import*
w=lambda n:0**n or kron(w(n-1),[[1,1],[1,-1]])

Спробуйте в Інтернеті!


0

Стакс , 20 байт

àΩ2┤â#╣_ê|ª⌐╦è│╞►═∞H

Запустіть і налагоджуйте його на staxlang.xyz!

Думав, я спробую через деякий час спробувати власний виклик. Нерекурсивний підхід. Не надто конкурентоспроможний проти інших мов для гольфу ...

Розпаковано (24 байти) та пояснення

|2c{ci{ci|&:B|+|1p}a*d}*
|2                          Power of 2
  c                         Copy on the stack.
   {                  }     Block:
    c                         Copy on stack.
     i                        Push iteration index (starts at 0).
      {           }           Block:
       ci                       Copy top of stack. Push iteration index.
         |&                     Bitwise and
           :B                   To binary digits
             |+                 Sum
               |1               Power of -1
                 p              Pop and print
                   a          Move third element (2^n) to top...
                    *         And execute block that many times.
                     d        Pop and discard
                       *    Execute block (2^n) times
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.