Produire le carré magique de Dürer


14

Le défi

Générez une représentation sous forme de tableau ou de chaîne du célèbre carré magique de Dürer :

entrez la description de l'image ici

C'est,

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

Certains propriétés de ce carré, qui peuvent peut-être être exploitées, sont:

  • Il contient chaque entier de 1 à 16exactement une fois
  • La somme de chaque colonne ou ligne, ainsi que la somme de chacune des deux diagonales, est la même. C'est la propriété qui définit un carré magique . La somme est la constante magique du carré.
  • De plus, pour ce carré particulier, la somme de chacun des quatre quadrants est également égale à la constante magique, tout comme la somme des quatre carrés centraux et la somme des quatre coins carrés.

Règles

Les Bultins qui génèrent des carrés magiques ne sont pas autorisés (comme Matlab magicou MathematicaMagicSquare ). Tout autre module intégré peut être utilisé.

Le code peut être un programme ou une fonction.

Il n'y a aucune entrée.

Les nombres doivent être en base 10. Le format de sortie est flexible comme d'habitude. Certaines possibilités sont:

  • Un tableau imbriqué (soit une sortie de fonction, soit sa représentation sous forme de chaîne, avec ou sans séparateurs, tout type de parenthèses correspondantes):

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

    {16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1}
    
  • Un tableau de quatre chaînes ou une chaîne composée de quatre lignes. Les chiffres peuvent être alignés à droite

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

    ou aligné à gauche

    16 3  2  13
    5  10 11  8
    9  6  7  12
    4  15 14  1
    
  • Une chaîne avec deux séparateurs différents pour la ligne et la colonne, tels que

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

Le format de sortie doit clairement différencier les lignes et les colonnes. Par exemple, il n'est pas autorisé de sortir un tableau plat ou une chaîne avec tous les nombres séparés par des espaces.

Code golf. Victoires les plus courtes.



4
Fait intéressant, les nombres 5, 8, 9 et 12 sont dans leurs positions (1 indexées), 6, 7, 10 et 11 ont été réfléchis verticalement, 2, 3, 14 et 15 ont été réfléchis horizontalement et 1, 4, 13 et 16 ont été tournés de 180 °. Je doute cependant que cela puisse aider quelqu'un.
Neil

2
Observation peut-être utile: si vous décrémentez 1 de chaque nombre, vous pouvez générer le carré en commençant par le tableau [15], puis en le concaténant à plusieurs reprises avec son inverse avec chaque élément XORed de 13, 3, 8 et 15, respectivement.
ETHproductions

6
Cela semble assez difficile à compresser dans des langues autres que le golf. je pense qu'un plus grand carré magique aurait fait mieux.
xnor

1
Je suis assez certain que chaque rotation ou réflexion du carré aurait les mêmes propriétés.
Dennis

Réponses:


7

Gelée , 15 octets

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

TryItOnline!

Assez ennuyeux, désolé:

Préparation: a pris le carré, l'a lu par lignes, converti de la base bijective 16, converti cela en base 250, a recherché les index de la page de codes pour ces "chiffres" ( ¡6ṡƘ[²Ḳi<).

Jelly lit ensuite les index pour faire un nombre de base 250, convertit en base bijective 16 ( ḃ⁴) et se divise en morceaux de taille 4 ( s4).


Si nous sommes autorisés à sortir une orientation différente, la tête en bas est possible en 14 :

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

Tester


En théorie, avec suffisamment de mémoire pour les 16!entiers, les éléments suivants nous donneraient l'orientation correcte dans 14 :

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

Cela créerait toutes les permutations de [1,16] avec ⁴Œ!et choisirait la valeur à l'index 19800593106060 (basé sur 1) avec l' utilisation de la représentation de base 250 ŒCġŀḌ;et la diviserait en morceaux de longueur 4 avec s4.


Depuis lors , j'ai ajouté quatre nouveaux atomes ( Œ?, Œ¿, œ?et œ¿) à Jelly pour répondre à ces situations.
La monade Œ?prend un entier (ou un itérable d'entiers) et retourne la permutation la plus courte possible des nombres naturels en cours d'exécution qui aurait l'index (ou les index) donné dans une liste de liste triée lexicographiquement de toutes les permutations de ces nombres.
... et il le fait sans créer de listes de permutation.
En tant que tel, les éléments suivants fonctionneraient désormais pour 12 (manifestement non concurrents):

“ŒCġŀḌ;’Œ?s4

Essayez!


Cela devrait être plus court dans votre fourchette Jelly (que j'avais oublié jusqu'à présent, désolé).
Dennis

Oh? Comment penses-tu?
Jonathan Allan

8

Pyth, 18 octets

c4.PC"H#ût"_S16

Exécutez le code.

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

Inverser la plage était censé abaisser l'indice de permutation, car la sortie commence par 16, mais je pense que cela n'a atteint que l'équilibre.

Cela a battu une stratégie plus ennuyeuse de conversion de la table directement en base 17, puis d'une chaîne ( lien ) pour 20 octets:

c4jC"úz(ás¸H"17 

7

Gelée , 16 15 octets

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

Essayez-le en ligne!

Contexte

Si nous soustrayons 1 des nombres dans le carré et les divisons par 4 (calcul du quotient et du reste), un modèle devient apparent.

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 restante suit un modèle évident et est facile à générer. La matrice de quotient peut être obtenue en transposant la matrice restante et en échangeant les rangées du milieu.

Comment ça fonctionne

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 octets

10 octets enregistrés grâce aux miles!

4 4$1+19800593106059 A.i.16

Maintenant avec moins ennuyeux! Cela prend la 19800593106059permutation de la liste i.16, qui est 15 2 1 12 4 9 10 7 8 5 6 11 3 14 13 0. Ensuite, qui est incrémenté, est ensuite façonné en une liste 4par 4.

Version alternative, sans espace:

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

Sortie, pour la postérité:

   _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

Je pense que ça _4]\1+19800593106059&A.i.16marche mais ça pourrait être raccourci peut
miles

@miles oo, bonne utilisation de A.. Comment avez-vous obtenu ce chiffre?
Conor O'Brien

Monadic A.trouve l'indice de permutation d'une permutation indexée zéro
miles

@miles hein. Je suppose que je devrais alors en savoir un peu plus sur ces fonctions.
Conor O'Brien

4

05AB1E , 18 17 octets

Merci à Emigna d' avoir enregistré un octet!

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

Utilise l' encodage CP-1252 . Essayez-le en ligne!


L'incrémentation avant la segmentation enregistre un octet ( >4ô).
Emigna

@Emigna Ahh, bien sûr! Merci! :)
Adnan

4

Ruby, 49 octets (plus court que la solution naïve!)

Il a fallu plusieurs tentatives pour rédiger un extrait de ce défi dans un langage courant qui était plus court que ce qu'il avait évalué! Selon les règles habituelles, j'en ai fait un programme en ajoutant un ppour le sortir.

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

Il génère (la représentation sous forme de chaîne de) un tableau de tableaux. C'est plus long que la solution Ruby de wat qui génère une chaîne de format différent, mais un octet plus court que le programme naïf ci-dessous qui renvoie simplement le tableau littéral.

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

Explication: commencez par les nombres 0..15 (38 octets!)

C’est là que j’ai commencé et c’est beaucoup plus facile. Si nous convertissons le carré 0..15 en binaire, nous notons que chaque cellule contient la valeur au bas de sa colonne XORed avec la valeur à droite de sa ligne:

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

De cela, nous dérivons le code ci-dessous. Mais en utilisant la première colonne au lieu de la dernière colonne, nous économisons un octet, comme indiqué.

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 version 1..16 requise était plus difficile. À la fin, j'ai réalisé que la façon de le faire était d'ajouter 1 à chaque cellule du carré 0..15. Mais comme ^la priorité est inférieure à celle dont +j'avais besoin, beaucoup de parenthèses, qui mangeaient des octets. Enfin, je suis tombé sur l'idée d'utiliser ^=. La nouvelle valeur de iest calculée par affectation augmentée ^=avant d'y ajouter le 1, de sorte que le calcul est effectué dans le bon ordre.


Belle caractérisation! Une réalisation simple Python est de 6 caractères ci - dessus hardcode: for a in 12,7,11,0:print[(a^b)+1for b in 3,14,13,0]. Il gagnerait si nous pouvions faire 0 à 15 avec for a in 12,7,11,0:print[a^3,a^14,a^13,a].
xnor

3

JavaScript (ES6), 43 octets

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

Séparé par des sauts de ligne, puis des virgules. Je doute qu'il existe un moyen plus court ...


Ouais, c'est probablement le plus court possible.
Conor O'Brien

2

sed 39 octets

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

Essayez-le en ligne!

Cela ne peut pas être beaucoup plus simple que cela. Et, malheureusement, je ne pense pas que cela puisse raccourcir non plus.


2

Gelée, 20 octets

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

Essayez-le en ligne!

Cela recherche simplement le point de code Jelly de chaque caractère, puis coupe en sous-réseaux de longueur 4 avec s4.


2

DASH , 24 octets

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

Remplacez les points par les caractères des codes de caractères 16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14 et 1 respectivement.

Explication

Convertit simplement les caractères en un tableau de charcodes et de morceaux par 4.


2

En fait , 22 octets

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

Essayez-le en ligne!

Explication:

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 octets / 46 octets

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

Analyser chacun comme chiffre hexidécimal et ajouter 1, assembler par 4 dans un tableau 2D.

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

Plus court, mais aussi plus léger:

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

2

Javascript ES6, 66 65 55 octets

Oui, ce n'est pas le plus court. Et oui, il peut être réduit.

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

Pour l'instant, ce n'est pas parfait. Mais c'est quelque chose!


Merci à la suggestion de @Neil qui pourrait économiser 5 à 8 octets et qui a inspiré @ETHproductions suggestion qui économise 10 octets!

Cela rend la réponse seulement 12 octets plus longue que sa solution de 43 octets .


1
Vous pouvez utiliser à la gplace de 0et à la parseInt(c,17)place, ce qui, je pense, vous économise 4 octets, ou vous pouvez utiliser + 0x${c}|| 16, ce qui, je pense, vous économise 5 octets, et vous pouvez ensuite soustraire 1 de tous les chiffres et l'ajouter plus tard, ce qui, je pense, vous fait gagner un autre octet.
Neil

1
En vous appuyant sur les suggestions de @ Neil, vous pouvez économiser au moins 10 octets au total .
ETHproductions

@Neil Merci beaucoup pour cette idée. L'utilisation de base17 permet d'économiser vraiment quelques octets. C'est vraiment quelque chose auquel je n'ai pas pensé.
Ismael Miguel

@ETHproductions Merci beaucoup pour la suggestion! J'essaie toujours de comprendre comment ça marche. Mais je pense que j'y arriverai. Maintenant, il suffit de raccourcir 13 octets pour vous battre. Mais il semble que votre réponse soit la plus courte possible en Javascript
Ismael Miguel

1

PowerShell v2 +, 40 octets

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

Une chaîne multiligne littérale, laissée sur le pipeline. La sortie via implicite Write-Outputse produit à la fin du programme. Agréable et ennuyeux.


Version construite, 77 octets

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

Prend la chaîne, -splits tous les quatre éléments, boucle sur eux, change chacun en hexadécimal 0x$_et ajoute 1, redirige vers iex(court Invoke-Expressionet similaire à eval), puis -joins le résultat dans une chaîne avec ,comme séparateur. Sort quatre chaînes sur le pipeline, avec une impression implicite.


1

Ruby, 60 octets - première tentative

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

Ruby, 45 octets - pas cher

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


1

05AB1E , 15 octets

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

Explication

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 de la permutation a été trouvé en utilisant la formule:

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

Où les variables sont remplacées par le nombre d'éléments successifs qui sont plus petits que le nombre à l'index actuel pour chaque nombre dans la liste cible
[16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1]

qui pour notre permutation recherchée est
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

Cela nous donne la formule: 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!

qui est égal à 19800593106059.


1

Matlab, 38 35 octets

Fonction anonyme:

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

Impression directe (38 octets):

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

Dans Matlab, la meilleure façon de produire un tableau d'entiers est d'utiliser une chaîne.


L'utilisation d'une fonction anonyme permettrait d'économiser quelques octets:@()['pcbm';'ejkh';'ifgl';'dnoa']-96
Luis Mendo

@LuisMendo Je n'ai pas remarqué que le retour de valeur est également acceptable, merci!
pajonk

1

Scala, 52 octets

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

Non golfé:

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

Inspiré par Level River St's - réponse rubis .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.