Produziere Dürers magisches Quadrat


14

Die Herausforderung

Gib ein Array oder eine String-Darstellung von Dürers berühmtem magischen Quadrat aus :

Bildbeschreibung hier eingeben

das ist,

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

Einige Eigenschaften dieses Quadrats, die möglicherweise ausgenutzt werden können, sind:

  • Es enthält jede Ganzzahl von 1bis 16genau einmal
  • Die Summe jeder Spalte oder Zeile sowie die Summe jeder der beiden Diagonalen ist gleich. Dies ist die definierende Eigenschaft eines magischen Quadrats . Die Summe ist die magische Konstante des Quadrats.
  • Darüber hinaus entspricht für dieses spezielle Quadrat die Summe der vier Quadranten ebenso wie die Summe der mittleren vier Quadrate und der Summe der vier Eckquadrate der magischen Konstante.

Regeln

Bultine, die magische Quadrate erzeugen, sind nicht erlaubt (wie Matlab's magicoder Mathematica's MagicSquare). Jedes andere eingebaute kann verwendet werden.

Der Code kann ein Programm oder eine Funktion sein.

Es erfolgt keine Eingabe.

Die Zahlen müssen zur Basis 10 gehören. Das Ausgabeformat ist wie gewohnt flexibel. Einige Möglichkeiten sind:

  • Ein verschachteltes Array (entweder Funktionsausgabe oder Zeichenfolgendarstellung mit oder ohne Trennzeichen, jede Art von übereinstimmenden Klammern):

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

    {16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1}
    
  • Ein Array von vier Zeichenfolgen oder eine Zeichenfolge, die aus vier Zeilen besteht. Die Zahlen können rechtsbündig sein

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

    oder linksbündig

    16 3  2  13
    5  10 11  8
    9  6  7  12
    4  15 14  1
    
  • Eine Zeichenfolge mit zwei unterschiedlichen Trennzeichen für Zeile und Spalte, z

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

Das Ausgabeformat sollte Zeilen und Spalten klar unterscheiden. Beispielsweise ist es nicht zulässig, ein flaches Array oder eine Zeichenfolge mit durch Leerzeichen getrennten Zahlen auszugeben.

Code Golf. Kürzeste Siege.



4
Interessanterweise befinden sich die Zahlen 5, 8, 9 und 12 in ihrer (1-indizierten) Position, 6, 7, 10 und 11 wurden vertikal reflektiert, 2, 3, 14 und 15 wurden horizontal reflektiert und 1, 4, 13 und 16 wurden um 180 ° gedreht. Ich bezweifle, dass das jemandem helfen wird.
Neil

2
Möglicherweise nützliche Beobachtung: Wenn Sie 1 von jeder Zahl dekrementieren, können Sie das Quadrat erzeugen, indem Sie mit dem Array beginnen [15]und es dann mit jedem durch 13, 3, 8 bzw. 15 XOR-verknüpften Element mit der Rückseite verketten.
ETHproductions

6
Dies scheint in nicht-golfenden Sprachen ziemlich schwer zu komprimieren zu sein. Ich denke, ein größeres magisches Quadrat hätte es besser gemacht.
Xnor

1
Ich bin ziemlich sicher, dass jede Drehung oder Reflexion des Quadrats die gleichen Eigenschaften haben würde.
Dennis

Antworten:


7

Gelee , 15 Bytes

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

TryItOnline!

Ziemlich langweilig, sorry:

Prep: Das Quadrat genommen, zeilenweise gelesen, von der bijektiven Basis 16 in die Basis 250 konvertiert, die Codepage-Indizes nach diesen "Ziffern" durchsucht ( ¡6ṡƘ[²Ḳi<).

Jelly liest dann die Indizes, um eine Zahl zur Basis 250 zu bilden, konvertiert zur bijektiven Basis 16 ( ḃ⁴) und teilt sich in Stücke der Größe 4 ( s4) auf.


Wenn wir eine andere Ausrichtung ausgeben dürfen, ist in 14 das Umkehren möglich :

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

Prüfung


Theoretisch 16!würde uns bei genügend Speicher für ganze Zahlen das Folgende die richtige Orientierung in 14 geben :

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

Dies würde alle Permutationen von [1,16] mit erstellen ⁴Œ!und den Wert am Index 19800593106060 (1-basiert) unter Verwendung der Basis-250-Darstellung auswählen ŒCġŀḌ;und ihn in Abschnitte der Länge 4 mit aufteilen s4.


Seitdem habe ich vier neue Atom hinzugefügt ( Œ?, Œ¿, œ?und œ¿) zu Jelly - Adresse solcher Situationen.
Die Monade Œ?nimmt eine ganze Zahl (oder eine Iteration von ganzen Zahlen) und gibt die kürzestmögliche Permutation von laufenden natürlichen Zahlen zurück, die den gegebenen Index (oder die Indizes) in einer Liste von lexikographisch sortierten Listen aller Permutationen dieser Zahlen hätten.
... und das, ohne Permutationslisten zu erstellen.
Als solches würde das Folgende nun für 12 funktionieren (offensichtlich nicht konkurrierend):

“ŒCġŀḌ;’Œ?s4

Probieren Sie es aus!


Dies sollte in Ihrer Jelly-Gabel kürzer sein (was ich bis jetzt vergessen hatte, sorry).
Dennis

Oh? Wie denkst du?
Jonathan Allan

8

Pyth, 18 Bytes

c4.PC"H#ût"_S16

Führen Sie den Code aus.

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

Das Umkehren des Bereichs sollte den Permutationsindex senken, da die Ausgabe mit 16 beginnt, aber ich denke, dass sie nur ausgeglichen ist.

Dies ist eine langweiligere Strategie, die Tabelle direkt in die Basis 17 und dann in eine Zeichenfolge ( Link ) für 20 Bytes umzuwandeln :

c4jC"úz(ás¸H"17 

7

Jelly , 16 15 Bytes

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

Probieren Sie es online!

Hintergrund

Subtrahieren wir 1 von den Zahlen im Quadrat und dividieren sie durch 4 (Berechnungsquotient und Rest), wird ein Muster sichtbar.

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

Die Restmatrix folgt einem offensichtlichen Muster und ist leicht zu erzeugen. Die Quotientenmatrix erhalten Sie, indem Sie die Restmatrix transponieren und die mittleren Reihen vertauschen.

Wie es funktioniert

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 Bytes

Dank Meilen 10 Bytes gespart!

4 4$1+19800593106059 A.i.16

Jetzt mit weniger langweilig! Dies geschieht durch die 19800593106059Permutation der Liste i.16, die ist 15 2 1 12 4 9 10 7 8 5 6 11 3 14 13 0. Dann wird das inkrementiert und dann zu einer 4By- 4Liste geformt .

Alternative Version ohne Leerzeichen:

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

Ausgabe für die Nachwelt:

   _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

Ich denke _4]\1+19800593106059&A.i.16funktioniert, aber es könnte möglicherweise kürzer gemacht werden
Meilen

@ Meilen oo, nette Verwendung von A.. Wie haben Sie diese Nummer gefunden?
Conor O'Brien

Monadic A.findet den Permutationsindex einer nullindexierten Permutation
Meilen

@ Meilen huh. Ich denke, ich sollte dann ein bisschen mehr über diese Funktionen lernen.
Conor O'Brien

4

05AB1E , 18 17 Bytes

Danke an Emigna für das Speichern eines Bytes!

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

Verwendet die CP-1252- Codierung. Probieren Sie es online!


Durch Inkrementieren vor dem Chunking wird ein Byte gespeichert ( >4ô).
Emigna

@Emigna Ahh, natürlich! Vielen Dank! :)
Adnan

4

Ruby, 49 Bytes (kürzer als die naive Lösung!)

Es dauerte einige Versuche, einen Ausschnitt für diese Herausforderung in einer Standardsprache zu schreiben, die kürzer war als das, was sie auswertete! Gemäß den üblichen Regeln habe ich ein Programm daraus gemacht, indem ich ein hinzugefügt habe, pum es auszugeben.

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

Es gibt (die Zeichenfolgendarstellung von) ein Array von Arrays aus. Es ist länger als die Ruby-Lösung von wat, die einen anders formatierten String ausgibt, aber ein Byte kürzer als das naive Programm darunter, das einfach das Literal-Array zurückgibt.

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

Erklärung: Beginnen Sie mit den Ziffern 0..15 (38 Bytes!)

Hier habe ich angefangen und es ist viel einfacher. Wenn wir das Quadrat 0..15 in ein Binärfeld konvertieren, stellen wir fest, dass jede Zelle den Wert am unteren Rand ihrer Spalte enthält, der mit dem Wert am rechten Rand ihrer Zeile XOR verknüpft ist:

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

Daraus leiten wir den folgenden Code ab. Indem wir jedoch die erste statt der letzten Spalte verwenden, sparen wir wie gezeigt ein Byte.

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

Die benötigte Version 1..16 war schwieriger. Am Ende wurde mir klar, dass ich zu jeder Zelle des 0..15-Quadrats 1 addieren musste. Aber da ^hat niedrigere Priorität als +ich brauchte eine Menge Klammern, die Bytes aßen. Endlich bin ich auf die Idee gekommen ^=. Der neue Wert von iwird durch erweiterte Zuweisung berechnet, ^=bevor die 1 hinzugefügt wird, sodass die Berechnung in der richtigen Reihenfolge erfolgt.


Schöne Charakterisierung! Eine einfache Realisierung in Python ist 6 Zeichen oben hard: for a in 12,7,11,0:print[(a^b)+1for b in 3,14,13,0]. Es würde gewinnen, wenn wir mit 0 bis 15 gewinnen könnten for a in 12,7,11,0:print[a^3,a^14,a^13,a].
2.

3

JavaScript (ES6), 43 Byte

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

Durch Zeilenumbrüche und Kommas getrennt. Ich bezweifle, dass es einen kürzeren Weg gibt ...


Ja, das ist wahrscheinlich die kürzeste.
Conor O'Brien


2

Gelee, 20 Bytes

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

Probieren Sie es online!

Dies schlägt einfach den Jelly-Code-Punkt jedes Zeichens nach und schneidet dann in Unterfelder der Länge 4 mit s4.


2

DASH , 24 Bytes

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

Ersetzen Sie die Punkte durch die Zeichen der Zeichencodes 16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14 und 1.

Erläuterung

Konvertiert die Zeichen einfach um 4 in ein Array von Zeichencodes und Chunks.


2

Eigentlich 22 Bytes

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

Probieren Sie es online!

Erläuterung:

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

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

Analysieren Sie jede als Hexadezimalziffer und addieren Sie 1 und 4 zu einem 2D-Array.

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

Kürzer, aber auch lamer:

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

2

Javascript ES6, 66 65 55 Bytes

Ja, es ist nicht die kürzeste. Und ja, es kann reduziert werden.

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

Im Moment ist es nicht perfekt. Ist aber was!


Vielen Dank an @Neil Vorschlags , der 5-8 Bytes einsparen könnte, und des inspirierenden Vorschlags von @ETHproductions , der 10 Bytes einspart!

Dies macht die Antwort nur 12 Bytes länger als seine 43 Bytes Lösung .


1
Sie könnten ganstelle von 0und parseInt(c,17)stattdessen verwenden, was Ihrer Meinung nach 4 Bytes spart, oder Sie könnten + 0x${c}|| 16 verwenden, was Ihrer Meinung nach 5 Bytes spart, und Sie könnten dann 1 von allen Ziffern subtrahieren und es später wieder hinzufügen. was ich denke erspart dir ein weiteres byte.
Neil

1
Aufbauend auf den Vorschlägen von @ Neil können Sie insgesamt mindestens 10 Byte einsparen .
ETHproductions

@ Neil Vielen Dank für die Idee. Die Verwendung von base17 spart wirklich ein paar Bytes. Es ist wirklich etwas, woran ich nicht gedacht habe.
Ismael Miguel

@ETHproductions Vielen Dank für den Vorschlag! Ich versuche immer noch zu verstehen, wie es funktioniert. Aber ich denke, ich werde es schaffen. Jetzt müssen Sie nur 13 Bytes kürzen, um Sie zu schlagen. Aber es scheint, dass Ihre Antwort die kürzestmögliche in Javascript ist
Ismael Miguel

1

PowerShell v2 +, 40 Byte

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

Eine wörtliche mehrzeilige Zeichenfolge, die in der Pipeline verbleibt. Die implizite Ausgabe Write-Outputerfolgt bei Programmabschluss. Schön und langweilig.


Konstruierte Version, 77 Bytes

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

Nimmt die Zeichenkette, setzt -splitsie alle vier Elemente auf, durchläuft sie als Schleife, ändert sie in ein Hex 0x$_und fügt hinzu 1, fügt diese zu iex(kurz für Invoke-Expressionund ähnlich zu eval), und setzt dann -joindas Ergebnis in eine Zeichenkette mit ,als Trennzeichen. Gibt vier Zeichenfolgen mit implizitem Druck auf der Pipeline aus.


1

Ruby, 60 Bytes - erster Versuch

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

Ruby, 45 Bytes - günstig

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


1

05AB1E , 15 Bytes

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

Erläuterung

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

Der Index der Permutation wurde unter Verwendung der Formel gefunden:

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

Dabei werden die Variablen durch die Anzahl der nachfolgenden Elemente ersetzt, die kleiner sind als die Anzahl am aktuellen Index für jede Nummer in der Zielliste
[16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1]

was für unsere gesuchte permutation ist
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

Dies gibt uns die Formel: 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!

das ist gleich 19800593106059.


1

Matlab, 38 35 Bytes

Anonyme Funktion:

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

Direktdruck (38 Bytes):

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

In Matlab ist die beste Möglichkeit, ein Array von Ganzzahlen zu erzeugen, eine Zeichenfolge.


Die Verwendung einer anonymen Funktion würde einige Bytes sparen:@()['pcbm';'ejkh';'ifgl';'dnoa']-96
Luis Mendo

@ LuisMendo Ich habe nicht bemerkt, dass der Rückgabewert auch akzeptabel ist, danke!
Pajonk

1

Scala, 52 Bytes

()=>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+)
  )

Inspiriert von Level River St's rubinroter Antwort .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.