Misalkan kita mendefinisikan matriks tak terbatas M
, pada N^2 -> {0, 1}
(di mana N
dimulai dari 1
alih-alih 0
) dengan cara ini:
M(1, 1)
=0
.Untuk setiap
x > 1
,M(x, 1)
=1
jikax
prima, dan0
sebaliknya.Untuk setiap
y > 1
,M(1, y)
=y
istilah ke dalamThue-Morse sequence
.Untuk setiap
x, y > 1
,M(x, y)
=M(x, y-1) + M(x-1, y) mod 2
.
Bagian kiri atas 16x16
dari matriks ini terlihat (dengan x
menjadi baris dan y
kolom):
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
1 0 1 1 0 0 0 1 0 0 0 1 1 0 1 1
1 1 0 1 1 1 1 0 0 0 0 1 0 0 1 0
0 1 1 0 1 0 1 1 1 1 1 0 0 0 1 1
1 0 1 1 0 0 1 0 1 0 1 1 1 1 0 1
0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 1
1 1 0 0 0 0 1 0 0 0 1 1 0 0 0 1
0 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1
0 1 0 1 0 1 1 1 1 1 0 0 0 0 0 1
0 1 1 0 0 1 0 1 0 1 1 1 1 1 1 0
1 0 1 1 1 0 0 1 1 0 1 0 1 0 1 1
0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 1
1 1 0 0 1 0 1 1 0 1 1 1 0 1 1 0
0 1 1 1 0 0 1 0 0 1 0 1 1 0 1 1
0 1 0 1 1 1 0 0 0 1 1 0 1 1 0 1
0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 1
Tugas Anda adalah membangun sebuah program yang akan mengevaluasi nilai entri sewenang-wenang dalam matriks ini seakurat mungkin.
Program Anda akan mengambil dua bilangan bulat x
dan y
sebagai input, dalam bentuk apa pun yang Anda pilih, dan kembali M(x, y)
, yang bisa berupa 0
atau 1
.
Kode Anda dapat ditulis dalam bahasa apa pun, tetapi tidak boleh melebihi 64 kilobyte (65.536 byte) dari ukuran kode sumber atau 2 MB (2.097.152 byte) dari total penggunaan memori. Program Anda harus mulai dengan memori kosong (mis. Itu tidak dapat memuat data dari tempat lain) dan berjalan secara independen untuk setiap input (artinya, ia mungkin tidak menyimpan data umum untuk beberapa kali dijalankan). Program Anda juga harus dapat mengevaluasi semua entri di kotak kiri atas 8192x8192
dalam jumlah waktu yang wajar.
Program yang mengevaluasi entri terbanyak dengan benar di kotak kiri atas 8192 x 8192
akan menjadi pemenang, dengan kode yang lebih pendek bertindak sebagai tie-breaker.
sumber
Jawaban:
J -
4238 charCukup cepat, 100% akurat, dan berada dalam batasan memori.
Strateginya adalah sebagai berikut: kami akan menghitung antidiagonal berturut-turut dari matriks ini, melakukan XOR berpasangan untuk bergerak bersama dan menambahkan Thue-Morse dan bit prima ke ujungnya. Kami kemudian menarik angka yang diperlukan dari antidiagonal ketika kami sampai di sana.
Penjelasan demi ledakan:
Penggunaan kata kerja ini adalah
x m y
untuk M (x, y) sebagaimana ditentukan dalam pertanyaan, di manam
kata kerjanya.Untuk menghemat penekanan tombol, kami tidak mencoba memberi tahu apakah kami masih membutuhkan lebih banyak bit prima atau Thue-Morse, jadi kami menghitung seluruh antidiagonal untuk mendapatkan bit yang kami inginkan. Namun,
8192 m 8192
masih berjalan dalam waktu kurang dari 0,07 dan sekitar 100 KiB pada laptop sederhana saya.sumber
Mathematica - Akurasi 100%,
223193189 byteIni adalah versi yang dapat dibaca:
Saya pada dasarnya melakukan precompute diagonal konstan
x+y
.Fitur:
O(x*y)
.f[8192,8192]
membutuhkan sekitar 400 detik. Saya kira ada ruang untuk perbaikan (mungkinRotateLeft
bisa menggantikan lingkaran dalam).Hanya menggunakan satu larik hingga
max(x,y)
hasil antara dalam memori. Jadi tidak ada keharusan untuk menggunakan lebih dari sekitar 32k (dengan asumsi bilangan bulat 32-bit) untuk algoritma itu sendiri (plus, apa pun yang digunakan Mathematica). Sebenarnya, Mathematica menggunakan 31M sendiri pada sistem saya, tetapi ini berfungsi tanpa masalah:sumber
O(x*y)
waktu, tetapi waktu eksekusi total meningkat lebih cepat dari itu. Saya tidak yakin apa yang terjadi. Jika beberapa Mathematica Guru dapat mencerahkan saya, operasi mana dalam loop tidakO(1)
itu akan sangat membantu! :) (baik,PrimeQ
danTotal@IntegerDigits
tidak, tapi saya sudah punya mereka di sana dari awal, dan mereka hanya meneleponO(y)
danO(x)
waktu masing-masing)Matlab: Akurasi 100%, 120 karakter, waktu eksekusi yang tidak masuk akal
Menggunakan:
sumber
M(8192, 8192)
, saya tidak bisa menerimanya.Python, 192 karakter
Akurasi 100%, menghitung M (8192.8192) dalam ~ 10 detik pada mesin saya.
sumber
Haskell - 261 byte - 100% - 1MB - Saya tidak berpikir ini akan berakhir dalam waktu dekat
Memakan waktu sekitar 10 detik untuk
m 16 16
dengan-O2
, tapi seperti yang saya tulis itu pula aku bisa menunjukkannya meskipun masalah ini:Mungkin beberapa Haskeller yang baik dapat mengoptimalkannya?
sumber
f p|p=not|0<1=id
harus lebih baik. juga, coba gunakanmorse = False : concat $ iterate [True] (\a -> a ++ map not a)
untuk meningkatkan kemalasan. Saya bertanya-tanya bagaimana ini akan mempengaruhi kinerja.True
ke0<1
danFalse
ke0>1
.Perl, 137
Bukan untuk 'menang' :-), tetapi karena belum ada Perl di sini dan kode tetap ditulis, ini dia.
Dibutuhkan beberapa detik jika dipanggil
print f(8192,8192)
, menyimpan satu baris matriks dalam memori (array 8192 integer (skalar)), sekitar 3,5 Mb seluruh proses Perl. Saya mencoba melakukannya dengan string, bukan array (baik dengan regexps atau mengakses dengan substr), membutuhkan lebih sedikit memori dan dapat golf lebih lanjut, tetapi berjalan lebih lambat.Bertakuk:
sumber
Haskell, 223
ini memiliki runtime cepat (5,7 detik dengan
-O3
). memori belum diperiksa, meskipun itu harus linier.ini menggunakan algoritma diagonal yang terlihat di sini sebelumnya.
sejauh menyangkut kecepatan, satu-satunya hal yang penting adalah algoritma diagonal
-O3
,, dan|foldr seq(0>1)s=0<1
penjaga, yang membuat daftar menjadi ketat. semuanya diimplementasikan dengan agak tidak efisien - pemeriksaan prima dilakukan dengan memeriksa semua angka yang lebih rendah untuk pembagian, elemen urutan Morse dihitung ulang secara konstan. tapi itu masih cukup cepat :-).sumber