Dürer'in sihirli karesini üretin


14

Meydan okuma

Dürer'in ünlü sihirli meydanının bir dizi veya dize temsilini çıktılayın :

resim açıklamasını buraya girin

yani,

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

Bu meydanın belki de istismar edilebilecek bazı özellikleri şunlardır:

  • Bu, her bir tamsayı içerir 1için 16tam olarak bir kere
  • Her bir sütunun veya satırın toplamının yanı sıra iki diyagonun her birinin toplamı aynıdır. Bu, sihirli bir karenin tanımlayıcı özelliğidir . Toplamıdır sihirli sabit kare.
  • Buna ek olarak, bu belirli kare için, dört çeyreğin her birinin toplamı, aynı zamanda merkez dört karenin toplamı ve köşe dört karenin toplamı gibi büyü sabitine eşittir.

kurallar

Sihirli kareler üreten bultinlere izin verilmez (Matlab magicveya Mathematica gibi MagicSquare). Başka herhangi bir yerleşik kullanılabilir.

Kod bir program veya işlev olabilir.

Hiçbir girdi yok.

Sayılar 10 tabanında olmalıdır. Çıktı biçimi her zamanki gibi esnektir. Bazı olasılıklar:

  • Yuvalanmış bir dizi (ayırıcılı veya ayırıcısız, herhangi bir eşleşen parantez türü olarak işlev çıktısı veya dize temsili):

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

    {16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1}
    
  • Dört dizeden oluşan bir dizi veya dört satırdan oluşan bir dize. Sayılar sağa hizalanmış olabilir

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

    veya sola hizalanmış

    16 3  2  13
    5  10 11  8
    9  6  7  12
    4  15 14  1
    
  • Satır ve sütun için iki farklı ayırıcıya sahip bir dize, örneğin

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

Çıktı formatı satırları ve sütunları açıkça ayırmalıdır. Örneğin, düz bir dizi veya tüm sayıların boşluklarla ayrılmış bir dize vermesine izin verilmez.

Kod golf. En kısa kazanç.



4
İlginç bir şekilde, 5, 8, 9 ve 12 sayıları (1 indeksli) pozisyonlarındadır, 6, 7, 10 ve 11 dikey olarak yansıtılmıştır, 2, 3, 14 ve 15 yatay olarak yansıtılmıştır ve 1, 4, 13 ve 16 tanesi 180 ° döndürüldü. Bunun kimseye yardım edeceğinden şüpheliyim.
Neil

2
Olası yararlı gözlem: her sayıdan 1 değerini düşürürseniz, diziden başlayarak ve [15]ardından sırasıyla 13, 3, 8 ve 15 XOR'lu her bir öğe ile tersi ile art arda birleştirerek kareyi oluşturabilirsiniz .
ETHproductions

6
Golf dışındaki dillerde sıkıştırmak oldukça zor görünüyor. bence daha büyük bir sihirli kare daha iyi olurdu.
xnor

1
Meydanın her dönüşünün veya yansımasının aynı özelliklere sahip olacağından eminim.
Dennis

Yanıtlar:


7

Jöle , 15 bayt

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

TryItOnline!

Çok sıkıcı, üzgünüm:

Hazırlık: Kareyi aldı, iki temel taban 16'dan dönüştürülen satırları okuyun, 250 tabanına dönüştürün, bu "basamaklar" ( ¡6ṡƘ[²Ḳi<) için kod sayfası dizinlerine baktı .

Jelly daha sonra bir taban 250 sayısı yapmak için indeksleri okur, iki yönlü tabana 16 ( ḃ⁴) dönüştürür ve 4 ( s4) boyutunda parçalara böler .


Farklı bir yönlendirme yapmamıza izin verilirse, 14'te baş aşağı mümkündür :

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

Ölçek


Teoride, 16!tamsayılar için yeterli hafıza verildiğinde , aşağıdakiler bize 14'te doğru yönelimi verecektir :

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

Bu, [1,16] 'nın tüm permütasyonlarını oluşturur ve taban 250 gösterimini kullanarak ⁴Œ!19800593106060 (1 tabanlı) endeksindeki değeri seçer ve 4 ile uzunluk parçalarına böler .ŒCġŀḌ;s4


O zamandan beri dört yeni atomu (ekledik Œ?, Œ¿, œ?ve œ¿adresi gibi durumlara Jelly).
Monad Œ?bir tamsayı alır (veya tamsayılar yinelenebilir) ve bu sayıların tüm permütasyonlarının sözlükbilimsel olarak sıralanmış bir listesinde belirli bir indekse (veya indekslere) sahip olacak doğal sayıları çalıştırmak için mümkün olan en kısa permütasyonu döndürür.
... ve bunu herhangi bir permütasyon listesi oluşturmadan yapar.
Aşağıdaki gibi, şu anda 12 için çalışacak (açıkçası rekabet etmiyor):

“ŒCġŀḌ;’Œ?s4

Bir Deneyin!


Bu Jelly çatalında daha kısa olmalı (şu ana kadar unuttum, üzgünüm).
Dennis

Ah? Nasıl düşünüyorsun?
Jonathan Allan

8

Pyth, 18 bayt

c4.PC"H#ût"_S16

Kodu çalıştırın.

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

Aralığı tersine çevirmek, çıkış 16 ile başladığı için permütasyon endeksini düşürmekti, ancak bence sadece eşit kırıldı.

Bu, tabloyu doğrudan temel 17'ye ve daha sonra 20 bayt için bir dize ( bağlantı ) dönüştürmek için daha sıkıcı bir strateji ortaya koydu:

c4jC"úz(ás¸H"17 

8

Jöle , 16 15 bayt

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

Çevrimiçi deneyin!

Arka fon

1'i karedeki sayılardan çıkarır ve 4'e bölersek (hesaplama bölümü ve kalan), bir desen ortaya çıkar.

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

Geri kalan matris bariz bir düzen izler ve üretilmesi kolaydır. Bölüm matrisi, geri kalan matrisin transpozisyonu ve orta sıraların değiştirilmesi ile elde edilebilir.

Nasıl çalışır

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 bayt

Mil sayesinde 10 bayt tasarruf!

4 4$1+19800593106059 A.i.16

Şimdi daha az sıkıcı! Bu 19800593106059listenin permütasyonunu alır i.16, yani 15 2 1 12 4 9 10 7 8 5 6 11 3 14 13 0. Sonra, bu artar, daha sonra bir 4yan 4liste halinde şekillendirilir .

Boşluk içermeyen alternatif sürüm:

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

Çıktı, gelecek nesiller için:

   _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

Bence _4]\1+19800593106059&A.i.16işe yarıyor ama muhtemelen daha kısa yapılabilir
mil

@miles oo, güzel kullanımı A.. Bu sayıyı nasıl bitirdiniz?
Conor O'Brien

Monadiç A., sıfır endeksli bir permütasyonun permütasyon endeksini bulur
mil

miles ha. Sanırım bu işlevler hakkında biraz daha bilgi edinmeliyim.
Conor O'Brien

4

05AB1E , 18 17 bayt

Bir bayt tasarrufu için Emigna'ya teşekkürler !

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

CP-1252 kodlamasını kullanır . Çevrimiçi deneyin!


Parçalamadan önceki artış bir bayt ( >4ô) kaydeder .
Emigna

@Emigna Ahh, elbette! Teşekkürler! :)
Adnan

4

Ruby, 49 bayt (naif çözümden daha kısa!)

Bu meydan okuma için, değerlendirdiği şeyden daha kısa olan ana dilde bir pasaj yazmak için birkaç girişimde bulunuldu! Her zamanki kurallara göre pçıktı almak için ekleyerek bir program yaptım.

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

Dizilerin bir dizisini çıktılar (dizge gösterimi). Farklı biçimlendirilmiş bir dize çıkaran wat'un Ruby çözümünden daha uzun, ancak basit diziyi döndüren aşağıdaki naif programdan bir bayt daha kısa.

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

Açıklama: 0..15 (38 bayt!) Rakamlarıyla başlayın.

Burası başladığım yer ve çok daha kolay. 0..15 karesini ikilik biçime dönüştürürsek, her hücrenin XORed sütununun altındaki değeri, satırının sağ tarafındaki değerle içerdiğini not ederiz:

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

Buradan aşağıdaki kodu elde ederiz. Ancak son sütun yerine ilk sütunu kullanarak, gösterildiği gibi bir bayt kaydederiz.

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

Gereken 1..16 sürümü daha zordu. Sonunda bunu yapmanın yolunu 0..15 karesinin her hücresine 1 eklemek olduğunu fark ettim. Ama benim ^önceliğimden daha +çok bayt yiyen parantezlere ihtiyacım var. Sonunda kullanma fikrine vurdum ^=. Yeni değeri , 1 eklenmeden önce iartırılmış atama ile hesaplanır ^=, böylece hesaplama doğru sırayla yapılır.


Güzel karakterizasyon! Python Basit bir gerçekleşme hardcode üstünde 6 karakter ise: for a in 12,7,11,0:print[(a^b)+1for b in 3,14,13,0]. Eğer 0 ila 15 yapabilseydik kazanırdı for a in 12,7,11,0:print[a^3,a^14,a^13,a].
xnor

3

JavaScript (ES6), 43 bayt

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

Yeni satırlar, ardından virgüllerle ayrılır. Daha kısa bir yol olduğundan şüpheliyim ...


Evet, bu muhtemelen en kısa olanıdır.
Conor O'Brien

2

sed 39 bayt

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

Çevrimiçi deneyin!

Bundan daha basit olamaz. Ve ne yazık ki, bunun daha kısa olabileceğini düşünmüyorum.



2

DASH , 24 bayt

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

Noktaları sırasıyla 16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14 ve 1 karakter kodlarıyla değiştirin.

açıklama

Karakterleri bir dizi karakter koduna dönüştürür ve 4'e kadar parçalar.


2

Aslında 22 bayt

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

Çevrimiçi deneyin!

Açıklama:

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

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

Her birini onaltılık basamak olarak ayrıştırın ve 1 ekleyin, 2 ile 2B diziye sıralayın.

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

Daha kısa, aynı zamanda lamer:

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

2

Javascript ES6, 66 65 55 bayt

Evet, en kısa olanı değil. Ve evet, azaltılabilir.

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

Şimdilik mükemmel değil. Ama bir şey!


Sayesinde @Neil 'ın 5-8 bayt kurtarabilecek öneri ve bu ilham @ETHproductions 10 bayt kaydeder öneri!

Bu, yanıtı 43 baytlık çözümden sadece 12 bayt daha uzun yapar .


1
Sen kullanabilirsiniz gyerine 0ve parseInt(c,17)ben, size 4 bayt kaydeder düşündüğümüz yerine veya + kullanabilirsiniz 0x${c}, sana 5 bayt kazandırdığını düşünüyor || 16, ve daha sonra tüm basamakları 1 çıkarma olabilir ve daha sonra geri ekleyin Sanırım başka bir bayt kurtarıyor.
Neil

1
@ Neil'in önerilerine dayanarak toplamda en az 10 bayt tasarruf edebilirsiniz .
ETHproductions

@Neil Bu fikir için çok teşekkür ederim. Base17 kullanmak gerçekten birkaç bayt tasarruf sağlar. Gerçekten düşünmediğim bir şey.
Ismael Miguel

@ETHproductions Öneri için çok teşekkür ederim! Hala nasıl çalıştığını anlamaya çalışıyorum. Ama sanırım oraya gideceğim. Şimdi, sizi yenmek için 13 baytı kısaltmanız gerekiyor. Ama cevabınız Javascript'te mümkün olan en kısa gibi görünüyor
Ismael Miguel

1

PowerShell v2 +, 40 bayt

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

Boru hattında bırakılmış bir çok satırlı dize. Örtük yoluyla çıktı Write-Output, program tamamlandığında olur. Güzel ve sıkıcı.


İnşa edilmiş sürüm, 77 bayt

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

Dizeyi alır, -splither dört öğede bir, üzerlerinde döngüler, her biri bir onaltılık olarak değiştirir 0x$_ve ekler 1, bunu iex(kısa Invoke-Expressionve benzeri eval) olarak borulara ekler , sonra -joinsonucu ,ayırıcı olarak bir dizgeye dönüştürür . Örtülü yazdırma ile dört dizeyi boru hattına çıktılar.


1

Ruby, 60 bayt - ilk deneme

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

Ruby, 45 bayt - ucuz

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


1

05AB1E , 15 bayt

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

açıklama

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

Permütasyon endeksi şu formül kullanılarak bulundu:

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

Değişkenlerin, hedef listedeki her sayı için geçerli dizindeki sayıdan daha küçük olan sonraki eleman sayısıyla değiştirildiği durumlarda
[16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1]

permütasyondan sonra aradığımız
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

Bu bize aşağıdaki formülü verir: 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!

eşittir 19800593106059.


1

Matlab, 38 35 bayt

Anonim işlev:

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

Doğrudan baskı (38 bayt):

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

Matlab'da bir tamsayı dizisi üretmenin en iyi yolu bir dize olsa da.


Anonim bir işlev kullanmak birkaç bayt tasarruf sağlar:@()['pcbm';'ejkh';'ifgl';'dnoa']-96
Luis Mendo

@LuisMendo Dönen değerin de kabul edilebilir olduğunu fark etmedim, teşekkürler!
pajonk

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.