Menghasilkan kotak ajaib Dürer


14

Tantangan

Keluarkan representasi array atau string dari kotak ajaib Dürer yang terkenal :

masukkan deskripsi gambar di sini

itu adalah,

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

Beberapa properti dari alun-alun ini, yang mungkin dapat dieksploitasi, adalah:

  • Ini berisi setiap bilangan bulat dari 1ke 16tepat satu kali
  • Jumlah setiap kolom atau baris, serta jumlah masing-masing dari kedua diagonal, adalah sama. Ini adalah properti yang menentukan dari sebuah kotak ajaib . Jumlahnya adalah konstanta ajaib alun-alun.
  • Selain itu, untuk kotak khusus ini, jumlah masing-masing dari empat kuadran juga sama dengan konstanta sihir, seperti halnya jumlah pusat empat kotak dan jumlah sudut empat kotak.

Aturan

Bultin yang menghasilkan kotak ajaib tidak diizinkan (seperti Matlab magicatau Mathematica MagicSquare). Setiap builtin lain dapat digunakan.

Kode dapat berupa program atau fungsi.

Tidak ada input.

Angka-angka harus dalam basis 10. Format output fleksibel seperti biasa. Beberapa kemungkinan adalah:

  • Array bersarang (output fungsi, atau representasi stringnya, dengan atau tanpa pemisah, semua jenis kurung yang cocok):

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

    {16, 3, 2, 13; 5, 10, 11, 8; 9, 6, 7, 12; 4, 15, 14, 1}
    
  • Array empat string, atau string yang terdiri dari empat baris. Angka-angka mungkin lurus kanan

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

    atau rata kiri

    16 3  2  13
    5  10 11  8
    9  6  7  12
    4  15 14  1
    
  • String dengan dua pemisah berbeda untuk baris dan kolom, seperti

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

Format output harus membedakan dengan jelas baris dan kolom. Misalnya, tidak diperbolehkan untuk menghasilkan array datar, atau string dengan semua angka yang dipisahkan oleh spasi.

Golf kode. Kemenangan terpendek.



4
Menariknya, angka 5, 8, 9 dan 12 berada pada posisi (1-diindeks), 6, 7, 10 dan 11 telah tercermin secara vertikal, 2, 3, 14 dan 15 telah tercermin secara horizontal dan 1, 4, 13 dan 16 telah diputar 180 °. Saya ragu itu akan membantu siapa pun.
Neil

2
Pengamatan yang mungkin berguna: jika Anda mengurangi 1 dari setiap angka, Anda dapat membuat kuadrat dengan memulai dengan array [15], lalu berulang kali menyatukannya dengan kebalikannya dengan setiap item XOR masing-masing sebesar 13, 3, 8, dan 15.
ETHproduksi

6
Ini agak sulit dikompres dalam bahasa non-golf. Saya pikir kotak ajaib yang lebih besar akan lebih baik.
xnor

1
Saya cukup yakin setiap rotasi atau refleksi alun-alun akan memiliki sifat yang sama.
Dennis

Jawaban:


7

Jelly , 15 byte

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

TryItOnline!

Cukup membosankan, maaf:

Prep: Mengambil kotak, membacanya dengan baris, dikonversi dari basis bijektif 16, mengubahnya menjadi basis 250, mencari indeks halaman kode untuk "digit" ( ¡6ṡƘ[²Ḳi<).

Jelly kemudian membaca indeks untuk membuat angka dasar 250, mengkonversi ke basis bijective 16 ( ḃ⁴) dan membelah menjadi potongan ukuran 4 ( s4).


Jika kita diizinkan untuk mengeluarkan orientasi yang berbeda, terbalik dimungkinkan dalam 14 :

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

Uji


Secara teori, diberikan memori yang cukup untuk 16!bilangan bulat berikut ini akan memberi kita orientasi yang benar dalam 14 :

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

Ini akan membuat semua permutasi [1,16] dengan ⁴Œ!dan memilih nilai pada indeks 19800593106060 (berbasis 1) dengan menggunakan representasi basis 250 ŒCġŀḌ;dan membaginya menjadi potongan dengan panjang 4 dengan s4.


Sejak itu saya telah menambahkan empat atom baru ( Œ?, Œ¿, œ?, dan œ¿) untuk Jelly ke alamat situasi seperti itu.
Monad Œ?mengambil integer (atau iterable of integer) dan mengembalikan permutasi sesingkat mungkin dari bilangan asli yang akan memiliki indeks (atau indeks) yang diberikan dalam daftar daftar diurutkan secara leksikografis dari semua permutasi dari angka-angka itu.
... dan ia melakukannya tanpa membuat daftar permutasi.
Dengan demikian, yang berikut ini akan berfungsi untuk 12 (jelas tidak bersaing):

“ŒCġŀḌ;’Œ?s4

Mencobanya!


Ini seharusnya lebih pendek di garpu Jelly Anda (yang saya lupa sampai sekarang, maaf).
Dennis

Oh Bagaimana menurut Anda?
Jonathan Allan

8

Pyth, 18 byte

c4.PC"H#ût"_S16

Jalankan kodenya.

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

Membalikkan rentang dimaksudkan untuk menurunkan indeks permutasi, karena output dimulai dengan 16, tapi saya pikir itu hanya mencapai titik impas.

Ini mengalahkan strategi yang lebih membosankan dari mengkonversi tabel langsung ke basis 17 dan kemudian string ( tautan ) selama 20 byte:

c4jC"úz(ás¸H"17 

7

Jelly , 16 15 byte

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

Cobalah online!

Latar Belakang

Jika kita mengurangi 1 dari angka dalam kuadrat dan membaginya dengan 4 (menghitung hasil bagi dan sisanya), sebuah pola menjadi jelas.

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

Matriks sisa mengikuti pola yang jelas dan mudah dihasilkan. Matriks hasil bagi dapat diperoleh dengan mentransposkan sisa matriks dan menukar baris tengah.

Bagaimana itu bekerja

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

Disimpan 10 byte berkat mil!

4 4$1+19800593106059 A.i.16

Sekarang dengan kurang membosankan! Ini mengambil 19800593106059permutasi daftar i.16, yaitu 15 2 1 12 4 9 10 7 8 5 6 11 3 14 13 0. Kemudian, yang bertambah, kemudian dibentuk menjadi 4oleh 4daftar.

Versi alternatif, tanpa spasi putih:

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

Output, untuk anak cucu:

   _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

Saya pikir itu _4]\1+19800593106059&A.i.16berhasil tetapi bisa dibuat lebih pendek
mil

@miles oo, penggunaan yang bagus A.. Bagaimana Anda menemukan nomor itu?
Conor O'Brien

Monadic A.menemukan indeks permutasi dari permutasi yang diindeks nol
mil

@miles huh. Saya kira saya harus belajar lebih banyak tentang fungsi-fungsi itu.
Conor O'Brien

4

05AB1E , 18 17 byte

Terima kasih kepada Emigna karena telah menghemat satu byte!

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

Menggunakan pengkodean CP-1252 . Cobalah online!


Menambah sebelum memotong menghemat satu byte ( >4ô).
Emigna

@Emigna Ahh, tentu saja! Terima kasih! :)
Adnan

4

Ruby, 49 byte (lebih pendek dari solusi naif!)

Butuh beberapa upaya untuk menulis cuplikan untuk tantangan ini dalam bahasa umum yang lebih pendek daripada yang dievaluasi! Seperti biasa, saya membuat program dengan menambahkan ap ke keluaran.

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

Ini menghasilkan (representasi string) array array. Ini lebih panjang daripada solusi Ruby wat yang menghasilkan string dengan format berbeda, tetapi satu byte lebih pendek dari program naif di bawah ini yang hanya mengembalikan array literal.

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

Penjelasan: mulai dengan angka 0..15 (38 byte!)

Di sinilah saya mulai dan itu jauh lebih mudah. Jika kita mengonversi kuadrat 0..15 menjadi biner, kami perhatikan bahwa setiap sel berisi nilai di bagian bawah kolomnya XOR dengan nilai di sisi kanan barisnya:

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

Dari sini kita mendapatkan kode di bawah ini. Tetapi dengan menggunakan kolom pertama dan bukan kolom terakhir, kami menyimpan satu byte, seperti yang ditunjukkan.

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

Versi 1..16 yang diperlukan lebih sulit. Pada akhirnya saya menyadari cara untuk melakukannya adalah dengan menambahkan 1 ke setiap sel dari 0,15 persegi. Tetapi karena ^memiliki prioritas lebih rendah daripada yang +saya butuhkan banyak kurung, yang memakan byte. Akhirnya saya menemukan ide untuk menggunakan ^=. Nilai baru idihitung dengan penugasan augmented ^=sebelum 1 ditambahkan ke dalamnya, sehingga perhitungan dilakukan dalam urutan yang benar.


Karakterisasi yang bagus! Sebuah realisasi sederhana dengan Python adalah 6 karakter di atas hardcode: for a in 12,7,11,0:print[(a^b)+1for b in 3,14,13,0]. Itu akan menang jika kita bisa melakukan 0 hingga 15 dengan 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`

Dipisahkan oleh baris baru, lalu koma. Saya ragu ada cara yang lebih pendek ...


Ya, ini mungkin yang sesingkat mungkin.
Conor O'Brien

2

sed 39 byte

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

Cobalah secara Online!

Tidak bisa lebih sederhana dari ini. Dan, sayangnya, saya tidak berpikir itu bisa menjadi lebih pendek juga.


2

Jelly, 20 byte

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

Cobalah online!

Ini hanya mencari titik kode Jelly masing-masing karakter, kemudian mengiris ke dalam subarrays dengan panjang 4 dengan s4.


2

DASH , 24 byte

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

Ganti periode dengan karakter kode karakter 16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, dan 1.

Penjelasan

Cukup konversi karakter ke array kode dan potongan oleh 4.


2

Sebenarnya , 22 byte

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

Cobalah online!

Penjelasan:

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)​

Parsing masing-masing sebagai digit heksidimal dan tambahkan 1, susun dengan 4 menjadi array 2D.

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

Lebih pendek, tetapi juga lamer:

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

2

Javascript ES6, 66 65 55 byte

Ya, itu bukan yang terpendek. Dan ya, itu bisa dikurangi.

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

Untuk saat ini, itu tidak sempurna. Tapi ada sesuatu!


Berkat @ Neil saran 's yang bisa menyelamatkan 5-8 byte, dan bahwa terinspirasi @ETHproductions saran yang menyimpan 10 byte!

Ini membuat jawabannya hanya 12 byte lebih lama dari solusi 43 byte nya .


1
Anda dapat menggunakan galih-alih 0dan parseInt(c,17)sebaliknya, yang menurut saya menyelamatkan Anda 4 byte, atau Anda dapat menggunakan + 0x${c}|| 16, yang menurut saya menghemat 5 byte, dan kemudian Anda dapat mengurangi 1 dari semua digit dan menambahkannya kembali nanti, yang saya pikir menghemat satu byte lagi.
Neil

1
Berdasarkan saran @ Neil, Anda dapat menyimpan setidaknya 10 byte secara total .
ETHproduk

@Neil Terima kasih banyak untuk idenya. Menggunakan base17 benar-benar menghemat beberapa byte. Ini benar-benar sesuatu yang saya tidak pikirkan.
Ismael Miguel

@ ETHproductions Terima kasih banyak atas sarannya! Saya masih mencoba memahami cara kerjanya. Tapi saya pikir saya akan sampai di sana. Sekarang, hanya perlu mempersingkat 13 byte untuk mengalahkan Anda. Tetapi tampaknya jawaban Anda adalah yang sesingkat mungkin dalam Javascript
Ismael Miguel

1

PowerShell v2 +, 40 byte

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

String multiline literal, ditinggalkan di jalur pipa. Output melalui implisit Write-Outputterjadi pada penyelesaian program. Bagus dan membosankan.


Versi yang dibangun, 77 byte

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

Mengambil string, -splitsetiap empat elemen, loop pada mereka, mengubah masing-masing menjadi hex 0x$_dan menambahkan 1, pipa yang menjadi iex(kependekan Invoke-Expressiondan mirip dengan eval), kemudian -joins hasilnya menjadi string dengan ,sebagai pemisah. Output empat string ke dalam pipa, dengan pencetakan implisit.


1

Ruby, 60 byte - upaya pertama

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

Ruby, 45 byte - murah

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


1

05AB1E , 15 byte

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

Penjelasan

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 permutasi ditemukan menggunakan rumus:

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

Di mana variabel diganti dengan jumlah elemen berikutnya yang lebih kecil dari jumlah pada indeks saat ini untuk setiap nomor dalam daftar target
[16, 3, 2, 13, 5, 10, 11, 8, 9, 6, 7, 12, 4, 15, 14, 1]

yang untuk permutasi kita dicari adalah
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

Ini memberi kita rumus: 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!

yang sama dengan 19800593106059.


1

Matlab, 38 35 byte

Fungsi anonim:

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

Pencetakan langsung (38 byte):

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

Dalam Matlab cara terbaik untuk menghasilkan array bilangan bulat adalah string.


Menggunakan fungsi anonim akan menghemat beberapa byte:@()['pcbm';'ejkh';'ifgl';'dnoa']-96
Luis Mendo

@LuisMendo Saya tidak melihat bahwa nilai pengembalian juga dapat diterima, terima kasih!
pajonk

1

Scala, 52 byte

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

Tidak Disatukan:

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

Terinspirasi oleh Tingkat Sungai St ini jawaban ruby .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.