Wyprodukuj magiczny kwadrat Dürera


14

Wyzwanie

Wydrukuj tablicę lub ciąg znaków słynnego magicznego kwadratu Dürera :

wprowadź opis zdjęcia tutaj

to jest,

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

Niektóre właściwości tego kwadratu, które być może można wykorzystać, to:

  • Zawiera każdą liczbę całkowitą od 1do 16dokładnie raz
  • Suma każdej kolumny lub wiersza, a także suma każdej z dwóch przekątnych, jest taka sama. Jest to właściwość definiująca magiczny kwadrat . Suma jest stałą magiczną kwadratu.
  • Ponadto dla tego konkretnego kwadratu suma każdej z czterech ćwiartek równa się również stałej magicznej, podobnie jak suma środkowych czterech kwadratów i suma narożnych czterech kwadratów.

Zasady

Bultiny generujące magiczne kwadraty są niedozwolone (takie jak Matlaba magiclub Mathematiki MagicSquare). Można użyć dowolnego innego wbudowanego.

Kod może być programem lub funkcją.

Brak danych wejściowych.

Liczby muszą być w bazie 10. Format wyjściowy jest elastyczny jak zwykle. Niektóre możliwości to:

  • Zagnieżdżona tablica (wyjście funkcji lub jej ciąg znaków, z separatorami lub bez, dowolny typ pasujących nawiasów):

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

    {16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1}
    
  • Tablica czterech ciągów lub ciąg składający się z czterech wierszy. Liczby mogą być wyrównane do prawej

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

    lub wyrównany do lewej

    16 3  2  13
    5  10 11  8
    9  6  7  12
    4  15 14  1
    
  • Ciąg z dwoma różnymi separatorami dla wiersza i kolumny, na przykład

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

Format wyjściowy powinien wyraźnie różnicować wiersze i kolumny. Na przykład nie można wypisać płaskiej tablicy lub łańcucha ze wszystkimi liczbami oddzielonymi spacjami.

Kod golfa. Najkrótsze wygrane.



4
Co ciekawe, liczby 5, 8, 9 i 12 znajdują się w swoich (1-indeksowanych) pozycjach, 6, 7, 10 i 11 zostały odzwierciedlone w pionie, 2, 3, 14 i 15 zostały odzwierciedlone w poziomie, a 1, 4, 13 a 16 zostało obróconych o 180 °. Wątpię, żeby to komukolwiek pomogło.
Neil

2
Prawdopodobnie przydatna obserwacja: jeśli zmniejszysz 1 z każdej liczby, możesz wygenerować kwadrat, zaczynając od tablicy [15], a następnie wielokrotnie łącząc ją z jej odwrotnością z każdym elementem XOR odpowiednio przez 13, 3, 8 i 15.
ETHproductions

6
Wydaje się to raczej trudne do kompresji w językach innych niż golf. Myślę, że większy magiczny kwadrat byłby lepszy.
xnor 31.10.16

1
Jestem całkiem pewien, że każdy obrót lub odbicie kwadratu miałby takie same właściwości.
Dennis

Odpowiedzi:


7

Galaretka , 15 bajtów

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

TryItOnline!

Bardzo nudno, przepraszam:

Przygotowanie: Wziąłem kwadrat, odczytałem go wierszami, przekonwertowałem z bazy bijective 16, przekonwertowałem na bazę 250, sprawdziłem indeksy stron kodowych dla tych „cyfr” ( ¡6ṡƘ[²Ḳi<).

Galaretka następnie odczytuje indeksy, aby utworzyć podstawową liczbę 250, przekształca się w bazę bijective 16 ( ḃ⁴) i dzieli na kawałki o wielkości 4 (s4 ).


Jeśli wolno nam wyprowadzić inną orientację, możliwe jest odwrócenie w 14 :

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

Test


Teoretycznie, biorąc pod uwagę wystarczającą ilość pamięci dla 16!liczb całkowitych, poniższe daje nam poprawną orientację w 14 :

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

Spowoduje to utworzenie wszystkich permutacji [1,16] ⁴Œ!zi wybranie wartości o indeksie 19800593106060 (w oparciu o 1) przy użyciu podstawowej reprezentacji 250 ŒCġŀḌ;i podzielenie jej na kawałki o długości 4 za pomocą s4.


Od tego czasu dodano cztery nowe węgla ( Œ?, Œ¿, œ?i œ¿) do pszczelego do takich sytuacji.
Monada Œ?przyjmuje liczbę całkowitą (lub iterowalną liczbę całkowitą) i zwraca najkrótszą możliwą permutację działania liczb naturalnych, która miałaby dany indeks (lub indeksy) na liście posortowanej leksykograficznie listy wszystkich permutacji tych liczb.
... i robi to bez tworzenia list permutacji.
W związku z tym poniższe elementy będą działać dla 12 (oczywiście niekonkurujących):

“ŒCġŀḌ;’Œ?s4

Dać mu szansę!


Powinno być krótsze w widelcu Jelly (o którym do tej pory zapomniałem, przepraszam).
Dennis

O? Jak myślisz?
Jonathan Allan

8

Pyth, 18 bajtów

c4.PC"H#ût"_S16

Uruchom kod.

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

Odwrócenie zakresu miało na celu obniżenie wskaźnika permutacji, ponieważ dane wyjściowe zaczynają się od 16, ale myślę, że nawet się złamał.

To pokonało bardziej nudną strategię konwersji tabeli bezpośrednio na bazę 17, a następnie ciąg ( link ) na 20 bajtów:

c4jC"úz(ás¸H"17 

7

Galaretka , 16 15 bajtów

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

Wypróbuj online!

tło

Jeśli odejmiemy 1 od liczb w kwadracie i podzielimy je przez 4 (obliczając iloraz i resztę), wzór staje się widoczny.

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

Pozostała matryca ma oczywisty wzór i jest łatwa do wygenerowania. Macierz ilorazową można uzyskać przez przeniesienie pozostałej macierzy i zamianę środkowych rzędów.

Jak to działa

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 bajtów

Zaoszczędzone 10 bajtów dzięki kilometrom!

4 4$1+19800593106059 A.i.16

Teraz mniej nudne! To wymaga 19800593106059permutacji listy i.16, która jest 15 2 1 12 4 9 10 7 8 5 6 11 3 14 13 0. Następnie jest to zwiększane, a następnie przekształcane w znak „ 4by”4 liście.

Alternatywna wersja bez białych znaków:

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

Wyjście dla potomności:

   _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

Myślę, że _4]\1+19800593106059&A.i.16działa, ale można go skrócić
mile

@miles oo, niezłe wykorzystanie A.. Jak sfinalizowałeś ten numer?
Conor O'Brien

Monadic A.znajduje indeks permutacji permutacji o indeksie zerowym
mile

@miles huh. Chyba powinienem się wtedy trochę dowiedzieć o tych funkcjach.
Conor O'Brien

4

05AB1E , 18 17 bajtów

Dzięki Emignie za uratowanie bajtu!

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

Wykorzystuje kodowanie CP-1252 . Wypróbuj online!


Zwiększanie przed dzieleniem zapisuje bajt ( >4ô).
Emigna,

@Emigna Ahh, oczywiście! Dzięki! :)
Adnan

4

Ruby, 49 bajtów (mniej niż naiwne rozwiązanie!)

Podjęto sporo prób napisania krótkiego fragmentu tego wyzwania w głównym nurcie języka, który był krótszy niż to, co ocenił! Zgodnie ze zwykłymi regułami stworzyłem z niego program, dodając pdo niego wyjście.

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

Wyprowadza (ciąg znaków) tablicę tablic. Jest on dłuższy niż rozwiązanie Ruby firmy Wat, które generuje łańcuch o innym formacie, ale jeden bajt jest krótszy niż naiwny program poniżej, który po prostu zwraca tablicę literałów.

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

Objaśnienie: zacznij od cyfr 0..15 (38 bajtów!)

Od tego zacząłem i jest o wiele łatwiej. Jeśli przekształcimy kwadrat 0..15 na binarny, zauważymy, że każda komórka zawiera wartość na dole kolumny XORed z wartością po prawej stronie swojego wiersza:

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

Z tego uzyskujemy poniższy kod. Ale używając pierwszej kolumny zamiast ostatniej kolumny, zapisujemy jeden bajt, jak pokazano.

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

Wymagana wersja 1..16 była trudniejsza. W końcu zdałem sobie sprawę, że można to zrobić, dodając 1 do każdej komórki kwadratu 0..15. Ale ponieważ ^ma niższy priorytet niż +potrzebowałem dużo nawiasów, które zjadły bajty. Wreszcie wpadłem na pomysł użycia ^=. Nowa wartość ijest obliczana na podstawie przypisania rozszerzonego ^=przed dodaniem do niej 1, więc obliczenia są wykonywane we właściwej kolejności.


Dobra charakterystyka! Prosta realizacja w Pythonie 6 znaków powyżej kodować: for a in 12,7,11,0:print[(a^b)+1for b in 3,14,13,0]. Wygrałby, gdybyśmy mogli zrobić 0 do 15 z for a in 12,7,11,0:print[a^3,a^14,a^13,a].
xnor

3

JavaScript (ES6), 43 bajty

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

Rozdzielone znakami nowej linii, a następnie przecinkami. Wątpię, żeby istniała krótsza droga ...


Tak, to prawdopodobnie najkrótsza możliwa.
Conor O'Brien

2

sed 39 bajtów

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

Wypróbuj online!

To nie może być dużo prostsze niż to. I niestety, nie sądzę, że może być krótszy.


2

Galaretka, 20 bajtów

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

Wypróbuj online!

Po prostu sprawdza punkt kodowy Jelly każdego znaku, a następnie kroi na podpowierzchnie o długości 4 za pomocą s4.


2

DASH , 24 bajty

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

Zamień kropki na znaki odpowiednio 16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14 i 1.

Wyjaśnienie

Po prostu konwertuje znaki na tablicę znaków i fragmentów o 4.


2

Właściwie 22 bajty

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

Wypróbuj online!

Wyjaśnienie:

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 bajtów / 46 bajtów

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

Przetwarzaj każdy jako cyfrę szesnastkową i dodaj 1, sortuj przez 4 do tablicy 2D.

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

Krótszy, ale także lamer:

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

2

JavaScript ES6, 66 65 55 bajtów

Tak, nie jest najkrótszy. I tak, można to zmniejszyć.

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

Na razie nie jest idealny. Ale jest coś!


Dzięki sugestii @Neil , która mogłaby zaoszczędzić 5-8 bajtów oraz inspirowanej sugestii @ETHproductions, która pozwala zaoszczędzić 10 bajtów!

To sprawia, że ​​odpowiedź jest tylko 12 bajtów dłuższa niż jego 43 bajtowe rozwiązanie .


1
Możesz użyć gzamiast 0i parseInt(c,17)zamiast, co moim zdaniem pozwala zaoszczędzić 4 bajty, lub możesz użyć + 0x${c}|| 16, co moim zdaniem pozwala zaoszczędzić 5 bajtów, a następnie możesz odjąć 1 od wszystkich cyfr i dodać go później, co myślę, że oszczędza ci kolejny bajt.
Neil

1
Opierając się na sugestiach @ Neila, możesz w sumie zaoszczędzić co najmniej 10 bajtów .
ETHprodukcje

@ Neil Dziękuję bardzo za pomysł. Korzystanie z base17 naprawdę oszczędza kilka bajtów. To naprawdę coś, o czym nie myślałem.
Ismael Miguel

@ETHproductions Dziękuję bardzo za sugestię! Wciąż próbuję zrozumieć, jak to działa. Ale myślę, że się tam dostanę. Teraz wystarczy skrócić 13 bajtów, aby cię pokonać. Ale wydaje się, że twoja odpowiedź jest najkrótsza z możliwych w JavaScript
Ismael Miguel

1

PowerShell v2 +, 40 bajtów

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

Dosłowny wieloliniowy ciąg pozostawiony na rurociągu. Wyjście za pośrednictwem niejawnego Write-Outputnastępuje po zakończeniu programu. Miło i nudno.


Wersja skonstruowana, 77 bajtów

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

Bierze ciąg, -splits co cztery elementy, zapętla je, zamienia każdy na heks 0x$_i dodaje 1, potokuje to iex(skrót do Invoke-Expressioni podobny do eval), a następnie -joins wynikiem w łańcuch z ,separatorem. Wysyła cztery ciągi do potoku, z niejawnym drukowaniem.


1

Ruby, 60 bajtów - pierwsza próba

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

Rubinowy, 45 bajtów - tanio

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


1

05AB1E , 15 bajtów

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

Wyjaśnienie

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

Indeks permutacji został znaleziony przy użyciu wzoru:

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

Gdzie zmienne są zastępowane liczbą kolejnych elementów, które są mniejsze niż liczba w bieżącym indeksie dla każdej liczby na liście docelowej
[16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1]

który dla naszej poszukiwanej permutacji jest
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

To daje nam wzór: 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!

co jest równe 19800593106059.


1

Matlab, 38 35 bajtów

Funkcja anonimowa:

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

Drukowanie bezpośrednie (38 bajtów):

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

W Matlabie najlepszym sposobem na utworzenie tablicy liczb całkowitych jest łańcuch.


Użycie anonimowej funkcji pozwoliłoby zaoszczędzić kilka bajtów:@()['pcbm';'ejkh';'ifgl';'dnoa']-96
Luis Mendo

@LuisMendo Nie zauważyłem, że zwracanie wartości jest również dopuszczalne, dzięki!
pajonk

1

Scala, 52 bajty

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

Nie golfowany:

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

Zainspirowany poziom rzeki st za rubinowym odpowiedź .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.