Genera una matrice Walsh


22

Una matrice Walsh è un tipo speciale di matrice quadrata con applicazioni nel calcolo quantistico (e probabilmente altrove, ma mi interessa solo il calcolo quantistico).

Proprietà delle matrici di Walsh

Le dimensioni sono le stesse potenza di 2. Pertanto, si può fare riferimento a queste matrici per l'esponente due di qui, chiamandoli W(0), W(1), W(2)...

W(0)è definito come [[1]].

Per n>0, W(n)sembra:

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

Quindi W(1)è:

[[1  1]
 [1 -1]]

Ed W(2)è:

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

Lo schema continua ...

Il tuo compito

Scrivi un programma o una funzione che accetta come input un numero intero ne stampa / ritorna W(n)in qualsiasi formato conveniente. Questo può essere un array di array, un array appiattito di booleani, .svgun'immagine, lo chiami tu, purché sia ​​corretta.

Sono vietate le scappatoie standard .

Un paio di cose:

Per W(0), la 1non necessità di essere avvolto anche una sola volta. Può essere un semplice numero intero.

Ti è permesso di 1 indice risultati - W(1)sarebbe quindi [[1]].

Casi test

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 -> pastebin

Questo è , quindi vince la soluzione più breve in ogni lingua! Buon golf!



I risultati possono essere 1 indicizzati? (es. W(1)ritorni [[1]], W(2)ritorni [[1,1],[1,-1]...)
Leo

@ Leo Sì, possono. A cura di.
Khuldraeseth na'Barya

Risposte:


7

Perl 6 , 63 44 40 byte

{map {:3(.base(2))%2},[X+&] ^2**$_ xx 2}

Provalo online!

Approccio non ricorsivo, sfruttando il fatto che il valore alle coordinate x, y è (-1)**popcount(x&y). Restituisce un array appiattito di booleani.

-4 byte grazie a xnor s' parità trucco po' .


10

MATL , 4 byte

W4YL

Provalo online!

Come funziona:

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

Senza il built-in: 11 byte

1i:"th1M_hv

Provalo online!

Come funziona :

Per ogni matrice Walsh W , la matrice successiva viene calcolata come [ W W ; W - W ], come descritto nella sfida. Il codice lo fa nvolte, a partire dalla matrice 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
Ugh ... e qui sto cercando di usare kron. ;)
becher


5

Ottava con built-in, 18 17 byte

@(x)hadamard(2^x)

Provalo online!

Ottava senza built-in, 56 51 47 byte

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

Provalo online! Grazie a @Luis Mendo per -4.

Ottava con lambda ricorsiva, 54 53 52 48 byte

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

Provalo online! Grazie a questa risposta e questa domanda per l'ispirazione.


Se la funzione è definita in un file, il secondo endnon è necessario. Quindi puoi spostarlo nell'intestazione di TIO e quindi rimuoverlo dal conteggio dei byte
Luis Mendo,


4

Python 2 , 75 71 byte

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

Provalo online!

La Walsh Matrix sembra essere collegata ai numeri malvagi. Se x&y(coordinate bit per bit e, base 0) è un numero malvagio, il valore nella matrice è 1, -1per i numeri odiosi. Il calcolo della parità dei bit int(bin(n),13)%2è tratto dal commento di Noodle9 su questa risposta .


2
Intuitivamente, il segno in (x, y) viene capovolto tante volte quanti sono i livelli di ricorsione su cui (x, y) si trova nel quadrante in basso a destra della matrice (2 ^ k × 2 ^ k), che si verifica quando xey hanno entrambi un 1 nel k-esimo bit. Usando questo fatto, possiamo semplicemente contare gli 1 bit x&yper determinare quante volte capovolgere il segno.
Lynn,

4

R , 61 56 53 50 byte

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

Provalo online!

Calcola ricorsivamente la matrice per prodotto Kronecker e restituisce 1 per n=0caso (grazie a Giuseppe per averlo segnalato, e anche a JAD per aver contribuito a giocare a golf nella versione iniziale).

Ulteriori -3 byte di nuovo grazie a Giuseppe.


Non so se il ritorno 1piuttosto che matrix(1)è valido, ma se lo è puoi giocare a golf e c'è anche un Reduceapproccio a 61 byte : provalo!
Giuseppe,

Non sono sicuro del formato del n=0caso, la maggior parte delle altre risposte lo avvolgono in [[1]], ma non tutti ...
Kirill L.

1
È possibile sostituire matrix(1)con t(1).
JAD

1
La domanda è stata modificata. È possibile restituire un numero intero anziché una matrice.
Khuldraeseth na'Barya,

1
1-2*!3:0è più breve di c(1,1,1,-1)tre byte.
Giuseppe,


2

JavaScript (ES6), 77 byte

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

Il calcolo ingenuo inizia prendendo 0 <= X, Y <= 2**Nin W[N]. Il caso semplice è quando uno dei due Xo Yè inferiore a 2**(N-1), nel qual caso si fa riferimento a X%2**(N-1)e Y%2**(N-1). Nel caso di entrambi Xe di Yessere almeno 2**(N-1)la chiamata ricorsiva deve essere annullata.

Se invece di eseguire il confronto Xo Ymeno di 2**(N-1)una maschera di bit, X&Y&2**(N-1)questo è diverso da zero quando la chiamata ricorsiva deve essere annullata e zero quando non lo è. Questo evita anche di ridurre il modulo 2**(N-1).

Naturalmente i bit possono essere testati in ordine inverso per lo stesso risultato. Quindi, invece di raddoppiare la maschera di bit ogni volta che coordiniamo, possiamo invece dimezzare, consentendo di XORed i risultati, per cui un risultato finale 0non significa negazione e 1significa negazione.




1

05AB1E , 16 byte

oFoL<N&b0м€g®smˆ

Provalo online!

Spiegazione

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

Vorrei sapere un modo più breve per calcolare il peso di Hamming.
1δ¢˜è della stessa lunghezza di 0м€g.


1

buccia , 13 byte

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

Provalo online!

1-indicizzati.

Spiegazione

!¡§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 byte

In mostra un paio di approcci usando librerie aggiuntive. Questo si basa su uno Scipy integrato:

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

Provalo online!

Python 2 , 65 byte

E questo usa solo Numpy e risolve dal prodotto Kronecker, analogamente alla mia risposta R :

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

Provalo online!


0

Stax , 20 byte

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

Eseguilo e esegui il debug su staxlang.xyz!

Ho pensato di provare la mia sfida dopo qualche tempo. Approccio non ricorsivo. Non troppo competitivo contro altre lingue del golf ...

Spacchettato (24 byte) e spiegazione

|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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.