Produci il quadrato magico di Dürer


14

La sfida

Stampa una matrice o una rappresentazione in formato stringa del famoso quadrato magico di Dürer :

inserisci qui la descrizione dell'immagine

questo è,

16  3  2 13
 5 10 11  8
 9  6  7 12
 4 15 14  1

Alcune proprietà di questa piazza, che possono forse essere sfruttate, sono:

  • Contiene ogni numero intero da 1a 16esattamente una volta
  • La somma di ciascuna colonna o riga, così come la somma di ciascuna delle due diagonali, è la stessa. Questa è la proprietà che definisce un quadrato magico . La somma è la costante magica del quadrato.
  • Inoltre, per questo particolare quadrato, la somma di ciascuno dei quattro quadranti equivale anche alla costante magica, così come la somma del centro quattro quadrati e la somma dell'angolo quattro quadrati.

Regole

I bultin che generano quadrati magici non sono ammessi (come Matlab magico Mathematica MagicSquare). È possibile utilizzare qualsiasi altro built-in.

Il codice può essere un programma o una funzione.

Non ci sono input.

I numeri devono essere nella base 10. Il formato di output è flessibile come al solito. Alcune possibilità sono:

  • Un array nidificato (output della funzione o rappresentazione della stringa, con o senza separatori, qualsiasi tipo di parentesi corrispondenti):

    [[16, 3, 2, 13], [5, 10, 11, 8], [9, 6, 7, 12], [4, 15, 14, 1]]
    
  • Un array 2D:

    {16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1}
    
  • Un array di quattro stringhe o una stringa composta da quattro righe. I numeri possono essere allineati a destra

    16  3  2 13
     5 10 11  8
     9  6  7 12
     4 15 14  1
    

    o allineato a sinistra

    16 3  2  13
    5  10 11  8
    9  6  7  12
    4  15 14  1
    
  • Una stringa con due diversi separatori per riga e colonna, ad esempio

    16,3,2,13|5,10,11,8|9,6,7,12|4,15,14,1
    

Il formato di output dovrebbe differenziare chiaramente righe e colonne. Ad esempio, non è consentito produrre un array piatto o una stringa con tutti i numeri separati da spazi.

Codice golf. Vittorie più brevi.



4
È interessante notare che i numeri 5, 8, 9 e 12 sono nelle loro posizioni (1 indicizzate), 6, 7, 10 e 11 sono stati riflessi verticalmente, 2, 3, 14 e 15 sono stati riflessi orizzontalmente e 1, 4, 13 e 16 sono stati ruotati di 180 °. Dubito che ciò aiuterà chiunque.
Neil,

2
Osservazione forse utile: se decrementi 1 da ciascun numero, puoi generare il quadrato iniziando con l'array [15], quindi concatenandolo ripetutamente con il suo rovescio con ogni elemento XORed rispettivamente di 13, 3, 8 e 15.
ETHproductions

6
Sembra piuttosto difficile comprimerlo in linguaggi non golfistici. penso che un quadrato magico più grande avrebbe fatto di meglio.
xnor

1
Sono abbastanza sicuro che ogni rotazione o riflesso del quadrato avrebbe le stesse proprietà.
Dennis,

Risposte:


7

Gelatina , 15 byte

“¡6ṡƘ[²Ḳi<’ḃ⁴s4

TryItOnline!

Abbastanza noioso, scusa:

Prep: Prese il quadrato, lo lesse per righe, convertito dalla base biiettiva 16, convertendolo in base 250, cercò gli indici della tabella codici per quelle "cifre" ( ¡6ṡƘ[²Ḳi<).

Jelly quindi legge gli indici per creare un numero di base 250, si converte in base biiettiva 16 ( ḃ⁴) e si divide in blocchi di dimensioni 4 ( s4).


Se ci è permesso di produrre un orientamento diverso, è possibile capovolgere in 14 :

“#⁷ƙ¤ṆWȷỤ’ḃ⁴s4

Test


In teoria, data sufficiente memoria per gli 16!interi, ciò che segue ci darebbe l'orientamento corretto in 14 :

⁴Œ!“ŒCġŀḌ;’ịs4

Ciò creerebbe tutte le permutazioni di [1,16] con ⁴Œ!e sceglierebbe il valore all'indice 19800593106060 (basato su 1) con l' utilizzo della rappresentazione di base 250 ŒCġŀḌ;e lo dividerebbe in blocchi di lunghezza 4 con s4.


Da allora ho aggiunto quattro nuovi atomi ( Œ?, Œ¿, œ?e œ¿) di gelatina per affrontare tali situazioni.
La monade Œ?prende un numero intero (o iterabile di numeri interi) e restituisce la permutazione più breve possibile di numeri naturali in esecuzione che avrebbero l'indice (o gli indici) dato in un elenco di elenco lessicograficamente ordinato di tutte le permutazioni di quei numeri.
... e lo fa senza creare alcun elenco di permutazioni.
Di conseguenza, i seguenti funzionerebbero ora per 12 (ovviamente non concorrenti):

“ŒCġŀḌ;’Œ?s4

Provaci!


Questo dovrebbe essere più corto nella tua forcella Jelly (che avevo dimenticato fino a quel momento, scusa).
Dennis

Oh? Come pensi?
Jonathan Allan,

8

Pyth, 18 byte

c4.PC"H#ût"_S16

Esegui il codice

c4.PC"H#ût"_S16

    C"H#ût"       Convert the packed string to the number 1122196781940
  .P       _S16   Take that-numbered permutation of the reversed range [16,15,...,1]
c4                Chop into piece of length 4

L'inversione dell'intervallo aveva lo scopo di abbassare l'indice di permutazione, poiché l'uscita inizia con 16, ma penso che si sia solo rotto.

Questo ha battuto una strategia più noiosa di convertire la tabella direttamente in base 17 e quindi una stringa ( collegamento ) per 20 byte:

c4jC"úz(ás¸H"17 

7

Gelatina , 16 15 byte

4Œ!.ịm0µZḂÞ’×4+

Provalo online!

sfondo

Se sottraiamo 1 dai numeri nel quadrato e li dividiamo per 4 (quoziente di calcolo e resto), un modello diventa evidente.

quotients and remainders    quotients    remainders

   3 3  0 2  0 1  3 0        3 0 0 3      3 2 1 0
   1 0  2 1  2 2  1 3        1 2 2 1      0 1 2 3
   2 0  1 1  1 2  2 3        2 1 1 2      0 1 2 3
   0 3  3 2  3 1  0 0        0 3 3 0      3 2 1 0

La matrice del resto segue uno schema ovvio ed è facile da generare. La matrice quoziente può essere ottenuta trasponendo la matrice rimanente e scambiando le file centrali.

Come funziona

4Œ!.ịm0µZḂÞ’×4+  Main link. No arguments.

4Œ!              Compute the array of all permutations of [1, 2, 3, 4], in
                 lexicographical order.
   .ị            Take the permutations at the indices adjacent to 0.5, i.e., the
                 ones at indices 0 ([4, 3, 2, 1]) and 1 ([1, 2, 3, 4]).
     m0          Concatenate the resulting [[4, 3, 2, 1], [1, 2, 3, 4]] with a
                 reversed copy, yielding the matrix
                 M := [[4, 3, 2, 1], [1, 2, 3, 4], [1, 2, 3, 4], [4, 3, 2, 1]].
       µ         Begin a new, monadic chain. Argument: M
        Z        Zip/transpose M, yielding the matrix
                 [[4, 1, 1, 4], [3, 2, 2, 3], [2, 3, 3, 2], [1, 4, 4, 1]].
         ḂÞ      Sort the rows by the lexicographical order of their parities,
                 yielding [[4, 1, 1, 4], [2, 3, 3, 2], [3, 2, 2, 3], [1, 4, 4, 1]].
           ’     Subtract 1 to yield the matrix of quotients, i.e.,
                 [[3, 0, 0, 3], [1, 2, 2, 1], [2, 1, 1, 2], [0, 3, 3, 0]].
            ×4+  Multiply the quotient by 4 and add the result to M (remainders).

5

J, 37 27 byte

Risparmiato 10 byte grazie alle miglia!

4 4$1+19800593106059 A.i.16

Ora con meno noioso! Questo prende la 19800593106059permutazione della lista i.16, che è 15 2 1 12 4 9 10 7 8 5 6 11 3 14 13 0. Poi, che viene incrementato, quindi è modellato in una 4da 4elenco.

Versione alternativa, senza spazi bianchi:

_4]\1+19800593106059&A.i.16

Uscita, per i posteri:

   _4]\1+19800593106059&A.i.16
16  3  2 13
 5 10 11  8
 9  6  7 12
 4 15 14  1
   4 4$1+19800593106059 A.i.16
16  3  2 13
 5 10 11  8
 9  6  7 12
 4 15 14  1

Penso che _4]\1+19800593106059&A.i.16funzioni ma potrebbe essere abbreviato possibilmente
miglia

@miles oo, buon uso di A.. Come hai finito con quel numero?
Conor O'Brien

Monadic A.trova l'indice di permutazione di una permutazione a indice zero
miglia

@miles huh. Immagino che dovrei imparare un po 'di più su quelle funzioni allora.
Conor O'Brien,

4

05AB1E , 18 17 byte

Grazie a Emigna per aver salvato un byte!

•3øѼž·Üý;•hSH>4ô

Utilizza la codifica CP-1252 . Provalo online!


L'incremento prima del blocco salva un byte ( >4ô).
Emigna

@Emigna Ahh, certo! Grazie! :)
Adnan,

4

Ruby, 49 byte (più breve della soluzione ingenua!)

Ci sono voluti parecchi tentativi per scrivere uno snippet per questa sfida in un linguaggio tradizionale più breve di quello a cui è stato valutato! Come al solito regole ne ho ricavato un programma aggiungendo a pper emetterlo.

p [15,4,8,3].map{|i|[1+i,1+i^=13,1+i^=3,1+i^=13]}

Emette (la rappresentazione in forma di stringa di) una matrice di array. È più lungo della soluzione Ruby di Wat che emette una stringa di formattazione diversa, ma un byte più breve del programma ingenuo di seguito che restituisce semplicemente l'array letterale.

p [[16,3,2,13],[5,10,11,8],[9,6,7,12],[4,15,14,1]] #naive solution, 50 bytes
p [15,4,8,3].map{|i|[1+i,1+i^=13,1+i^=3,1+i^=13]}  #submission, 49 bytes

Spiegazione: iniziare con i numeri 0..15 (38 byte!)

È qui che ho iniziato ed è molto più semplice. Se convertiamo il quadrato 0..15 in binario, notiamo che ogni cella contiene il valore nella parte inferiore della sua colonna XORed con il valore sul lato destro della sua riga:

15 2  1  12            1111 0010 0001 1100
4  9  10 7             0100 1001 1010 0111
8  5  6  11            1000 0101 0110 1011
3  14 13 0             0011 1110 1101 0000

Da ciò deriviamo il codice seguente. Usando la prima colonna invece dell'ultima colonna, salviamo un byte, come mostrato.

p [12,7,11,0].map{|i|[i^3,i^14,i^13,i]}            #0..15 square, 39 bytes         
p [15,4,8,3].map{|i|[i,i^13,i^14,i^3]}             #0..15 square, 38 bytes

La versione 1..16 richiesta era più difficile. Alla fine mi sono reso conto che il modo per farlo era quello di aggiungere 1 a ciascuna cella del quadrato 0..15. Ma dato che ^ha una priorità inferiore a quella di cui +avevo bisogno di molte parentesi, che mangiavano byte. Alla fine ho pensato all'idea di usare ^=. Il nuovo valore di iviene calcolato per assegnazione aumentata ^=prima che l'1 venga aggiunto ad esso, quindi il calcolo viene eseguito nell'ordine corretto.


Bella caratterizzazione! Un semplice realizzazione in Python è 6 caratteri sopra hardcode: for a in 12,7,11,0:print[(a^b)+1for b in 3,14,13,0]. Vincerebbe se potessimo fare 0 a 15 con for a in 12,7,11,0:print[a^3,a^14,a^13,a].
xnor

3

JavaScript (ES6), 43 byte

_=>`16,3,2,13
5,10,11,8
9,6,7,12
4,15,14,1`

Separato da newline, quindi virgole. Dubito che ci sia un modo più breve ...


Sì, questo è probabilmente il più breve possibile.
Conor O'Brien,

2

sed 39 byte

c16,3,2,13|5,10,11,8|9,6,7,12|4,15,14,1

Provalo online!

Non può essere molto più semplice di così. E, sfortunatamente, non penso nemmeno che possa essere più breve.


2

Gelatina, 20 byte

“Ѥ£Æ¦½¿®µ©¬€¥ÐÇ¢‘s4

Provalo online!

Questo cerca semplicemente il punto di codice Jelly di ogni personaggio, quindi si divide in sottoquarti di lunghezza 4 con s4 .


2

DASH , 24 byte

<|>4tc"................"

Sostituisci i punti con i caratteri dei codici caratteri 16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14 e 1 rispettivamente.

Spiegazione

Converte semplicemente i personaggi in una matrice di caratteri e blocchi di 4.


2

In realtà , 22 byte

4"►♥☻♪♣◙♂◘○♠•♀♦☼♫☺"♂┘╪

Provalo online!

Spiegazione:

4"►♥☻♪♣◙♂◘○♠•♀♦☼♫☺"♂┘╪
 "►♥☻♪♣◙♂◘○♠•♀♦☼♫☺"     push a string containing the numbers in the magic square, encoded as CP437 characters
                   ♂┘   convert to ordinals
4                    ╪  chunk into length-4 slices

2

Groovy, 57 byte / 46 byte

"F21C49A7856B3ED0".collect{Eval.me("0x$it")+1}​.collate(4)​

Analizzare ciascuno come cifra esadecimale e aggiungere 1, fascicolare per 4 in un array 2D.

[[16, 3, 2, 13], [5, 10, 11, 8], [9, 6, 7, 12], [4, 15, 14, 1]]

Più corto, ma anche più lento:

print '16,3,2,13|5,10,11,8|9,6,7,12|4,15,14,1'

2

Javascript ES6, 66 65 55 byte

Sì, non è il più corto. E sì, può essere ridotto.

_=>`f21c
49a7
856b
3ed0`.replace(/./g,_=>'0x'+_-~0+' ')

Per ora non è perfetto. Ma è qualcosa!


Grazie al suggerimento di @Neil che potrebbe salvare 5-8 byte e che ha ispirato il suggerimento di @ETHproductions che salva 10 byte!

Questo rende la risposta solo 12 byte più lunga della sua soluzione di 43 byte .


1
Potresti usare ginvece di 0e parseInt(c,17)invece, che penso ti salvi 4 byte, oppure potresti usare + 0x${c}|| 16, che penso ti salvi 5 byte, e quindi potresti sottrarre 1 da tutte le cifre e aggiungerlo più tardi, che penso ti salvi un altro byte.
Neil

1
Basandoti sui suggerimenti di @ Neil, puoi salvare almeno 10 byte in totale .
ETHproductions

@Neil Grazie mille per l'idea. L'uso di base17 fa davvero risparmiare qualche byte. È davvero qualcosa a cui non ho pensato.
Ismael Miguel,

@ETHproductions Grazie mille per il suggerimento! Sto ancora cercando di capire come funziona. Ma penso che ci arriverò. Ora, devi solo accorciare 13 byte per batterti. Ma sembra che la tua risposta sia la più breve possibile in Javascript
Ismael Miguel,

1

PowerShell v2 +, 40 byte

'16,3,2,13
5,10,11,8
9,6,7,12
4,15,14,1'

Una stringa multilinea letterale, lasciata sulla tubazione. L'output tramite implicito Write-Outputavviene al completamento del programma. Bello e noioso.


Versione costruita, 77 byte

'f21c59a7856b3dc0'-split'(....)'-ne''|%{([char[]]$_|%{"0x$_+1"|iex})-join','}

Prende la stringa, -splitogni quattro elementi, si avvolge su di essi, li trasforma ciascuno in un esagono 0x$_e aggiunge 1, i tubi in iex(corto Invoke-Expressione simile a eval), quindi -joinil risultato in una stringa con ,come separatore. Emette quattro stringhe sulla pipeline, con stampa implicita.


1

Rubino, 60 byte - primo tentativo

%w(f21c 49a7 856b 3ed0).map{|i|i.chars.map{|i|i.to_i(16)+1}}

Rubino, 45 byte - economico

puts '16,3,2,13|5,10,11,8|9,6,7,12|4,15,14,1'


1

05AB1E , 15 byte

16Lœ•iPNÍš¯•è4ä

Spiegazione

16L              # range [1 ... 16]
   œ             # compute all permutations of the range
    •iPNÍš¯•è    # take the permutation at index 19800593106059
             4ä  # split the permutation into 4 parts

L'indice della permutazione è stato trovato utilizzando la formula:

a*15! + b*14! + c*13!+ ... + o*1! + p*0!

Dove le variabili vengono sostituite con il numero di elementi successivi che sono più piccoli del numero nell'indice corrente per ciascun numero nell'elenco di destinazione
[16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1]

quale per la nostra permutazione ricercata è
a=15, b=2, c=1, d=10, e=2, f=6, g=6, h=4, i=4, j=2, k=2, l=2, m=1, n=2 o=1, p=0

Questo ci dà la formula: 15*15!+2*14!+1*13!+10*12!+2*11!+6*10!+6*9!+4*8!+4*7!+2*6!+2*5!+2*4!+1*3!+2*2!+1*1!+0*0!

che è uguale a 19800593106059.


1

Matlab, 38 35 byte

Funzione anonima:

@()['pcbm';'ejkh';'ifgl';'dnoa']-96

Stampa diretta (38 byte):

disp(['pcbm';'ejkh';'ifgl';'dnoa']-96)

In Matlab il modo migliore per produrre un array di numeri interi è attraverso una stringa.


L'uso di una funzione anonima risparmierebbe alcuni byte:@()['pcbm';'ejkh';'ifgl';'dnoa']-96
Luis Mendo,

@LuisMendo Non ho notato che anche il valore di ritorno è accettabile, grazie!
pajonk,

1

Scala, 52 byte

()=>Seq(15,4,8,3)map(x=>Seq(x,x^13,x^14,x^3)map(1+))

Ungolfed:

()=>
  Seq(15, 4, 8, 3)
  .map(x=>
    Seq(x, x^13, x^14, x^3)
    .map(1+)
  )

Ispirato del livello del fiume St risposta rubino .

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.