Sebuah sandpile abelian , untuk tujuan kita, adalah jaringan yang tak terbatas dengan koordinat bilangan bulat, awalnya kosong pasir. Setelah setiap detik, sebutir pasir ditempatkan pada (0,0). Setiap kali sel grid memiliki 4 atau lebih butir pasir, ia menumpahkan satu butir pasir ke masing-masing empat tetangganya secara bersamaan. Tetangga (x, y) adalah (x-1, y), (x + 1, y), (x, y-1), dan (x, y + 1).
Ketika sebuah sel tumpah, itu bisa menyebabkan tetangganya tumpah. Beberapa fakta:
- Kaskade ini pada akhirnya akan berhenti.
- Urutan di mana sel-sel tumpah tidak relevan; hasilnya akan sama.
Contoh
Setelah 3 detik, kotak terlihat seperti
.....
.....
..3..
.....
.....
Setelah 4 detik:
.....
..1..
.1.1.
..1..
.....
Setelah 15 detik:
.....
..3..
.333.
..3..
.....
Dan setelah 16 detik:
..1..
.212.
11.11
.212.
..1..
Tantangan
Dalam sesedikit mungkin byte, tulislah fungsi yang mengambil t bilangan bulat positif tunggal dan menghasilkan gambar tumpukan pasir setelah t detik.
Memasukkan
Satu bilangan bulat positif t , dalam format apa pun yang Anda pilih.
Keluaran
Gambar tumpukan pasir setelah t detik, menggunakan karakter
. 1 2 3
Sunting: Gunakan empat karakter berbeda yang Anda suka, atau buat gambar. Jika Anda tidak menggunakan ".123" atau "0123", tentukan dalam jawaban Anda apa yang ditandai oleh karakter.
Tidak seperti dalam contoh, output Anda harus mengandung jumlah minimum baris dan kolom yang diperlukan untuk menunjukkan bagian nol dari sandpile.
Artinya, untuk input 3, output harus
3
Untuk 4, output seharusnya
.1.
1.1
.1.
Mencetak gol
Berlaku standar skor golf.
Aturan
Tidak ada fungsi bahasa atau pustaka yang sudah tahu apa sandpile diperbolehkan.
Sunting: Bagian output telah diedit, batasan set karakter telah sepenuhnya diangkat. Gunakan empat karakter atau warna berbeda yang Anda suka.
sumber
0
? Apa ouput itu?.
sel kosong? Bisakah kita memiliki0
sel kosong yang valid?Jawaban:
R,
378343297291 byteSeperti biasa, pengguna memasok inputnya melalui
scan()
(saya sudah menggunakan variabelt
, jadi mari kita ambilz
sebagai gantinya), jadi baris kedua harus diluncurkan secara terpisah, dan kemudian sisanya:Menghasilkan array yang berisi nilai-nilai
a
padat
generasi ke-0 (0, 1, 2 atau 3).Kasus uji:
Ini membantu kita bahwa hal ini simetris baik secara vertikal maupun horizontal, yang berarti bahwa titik paling kiri mendapat ketinggian 4, ini berarti bahwa titik paling atas, paling kanan dan terendah juga 4.
Oh, dan apakah saya mengatakan bahwa Anda dapat membuat visualisasi yang indah?
Setelah 1000 tetes:
Setelah 50000 tetes (≈4 detik):
Setelah 333333 tetes (≈15 menit):
Anda bisa menggambarnya juga!
Hal ini membutuhkan waktu 4 detik untuk 10.000 iterasi tetapi melambat jauh untuk ukuran array yang lebih besar (misalnya beberapa menit untuk 100000 iterasi). Inilah sebabnya mengapa ia menjadi sangat lambat (saya memperkirakan tingkat pertumbuhan seperti pada dan memperoleh τ (i) ≈689 · i ^ 1.08, jadi waktu rata-rata per satu butir tambahan sampai seluruh tumpukan pasir mengendap setelah
i
langkah sedikit lebih besar dari satu) , dan total waktu sebagai fungsi dari jumlah butiran tumbuh sedikit lebih lambat daripada kuadratik (T (i) .00.028 * i ^ 1,74):Dan sekarang dengan penjelasan lengkap:
Ini adalah pertama kalinya dalam hidup saya ketika menumbuhkan objek (seperti
a <- c(a, 1)
) bekerja jauh lebih cepat daripada mengalokasikan matriks kosong yang besar untuk nilai-nilai dan mengisinya secara bertahap dengan satu ton nol yang tidak digunakan.Memperbarui. Golfed 18 byte dengan menghilangkan
arr.ind
dalamwhich
karena Billywob dan menggantirep(0,n)
dengane=numeric;e(n)
di 5 kasus karena JDL , dan 17 byte lagi karena JDL .Pembaruan 2. Karena tumpukan pasir adalah Abelian, itu mungkin dimulai dengan setumpuk ketinggian yang diinginkan, jadi saya menghapus loop berlebihan dan mendapatkan peningkatan besar dalam produktivitas!
sumber
rep()
, pra-penetapan , mengingat Anda menggunakannya 6 kali. Kedua, saya rasa Anda tidak perlu menuliskanarr.ind=T
opsi untukwhich()
fungsi tersebut. Cukup gunakanwhich(...,T)
.n=numeric
dan menggunakannya, karenan(k)
karakter lebih sedikit daripadar(0,k)
. Saya suka gambarnya.1%*%0
lebih sedikit karakter daripadaarray(0,c(1,1))
. Argumen kedua yangu <- cbind
bisa saja 1,cbind
akan memperpanjang ke panjang argumen pertama secara default.MATL ,
5553484342 byteTerinspirasi oleh jawaban @ flawr .
Output grafis :
Cobalah di MATL Online! . Diperlukan sekitar 10 detik untuk input
30
. Anda mungkin perlu me-refresh halaman dan tekan "Run" lagi jika itu tidak berhasil.Berikut ini contoh hasil untuk input
100
:Output ASCII (43 byte) :
Cobalah online!
Penjelasan
sumber
1Y6
.~mod(spiral(3),2)
jauh lebih pintar :-)Matlab,
160 156148 bytePertama cara matriks terlalu besar dibuat, dengan
n
di tengah suatu tempat. Kemudian cascading dihitung dengan konvolusi 2d yang sangat nyaman. Pada akhirnya kelebihan dipangkas dan semuanya dikonversi menjadi string.Contoh output untuk
t=100
Seperti biasa:
sumber
v=any(z)
alih-alihv=find(sum(z))
(saya menggunakan itu dalam jawaban saya). Juga,2*~z
bukannya(z<1)*2
n=500
... Itu telah diprosesn=400
selama beberapa detik. Apakah saya melakukan sesuatu yang salah?n
program ini menghasilkan sebuah3*n x 3*n
matriks, sehingga perlu menyimpan tentang9*n^2
angka. Juga sangat tidak efisien, karena kami juga memiliki iterasi panjang yang sama sekali tidak perlu dari 1 hingga n. Tetapi sekali lagi ini adalah kode-golf , membuat program yang efisien adalah secangkir teh yang berbeda.z=sparse(zeros(2*n+1))
dan mengubah for loop menjadiwhile any(z(:)>3)
. Kemudian Anda juga bisa mungkin menghitung kernel konvolusi hanya sekali:kern = 1-mod(spiral(3),2)
.Python 2,
195 +1 +24 = 220217output untuk n = 16
ada banyak padding dan iterasi yang tidak perlu, dengan menggunakan
n
sebagai batas atas "cukup baik", tetapi n = 200 masih selesai dalam detik dan n = 500 dalam waktu sekitar 12 detikungolfed
mengganti
return x
denganimshow(x)
menambahkan satu karakter dan menghasilkan gambar interpolasi jelek, menambahkanimshow(x,'gray',None,1,'nearest')
menghilangkan interpolasi buram membawa output hingga spesifikasisumber
ImportError: No module named convolve2d
. Mengubahimport scipy.signal.convolve2d as c
untukfrom scipy.signal import convolve2d as c
menyelesaikan masalah. Saya menggunakan versi scipy 0.16.1, apakah saya memerlukan versi yang lebih lama atau lebih baru? Atau apakah masalahnya berbeda?Perl,
157147 byteTermasuk +1 untuk
-p
Jalankan dengan hitungan pada STDIN, cetak peta menggunakan
0123
ke STDOUT:sandpile.pl
:sumber
Python
32,418385362342330 byteEdit: disimpan 6 byte berkat @ Qwerp-Derp
Semua pujian untuk @ Andreï Kostyrka, karena ini adalah terjemahan langsung dari kode R-nya ke Python.
sumber
a,x,r
ke argumen fungsi.JavaScript,
418416406400393 byteMenciptakan fungsi anonim yang menampilkan output di konsol.
sumber
Nim, 294 karakter
Kompilasi dan Jalankan:
Catatan:
x
dihitung sebagai jumlah kolom nol pada awal baris tengah.x
baris dan kolom dari masing-masing ujung.Performa
sumber
Scala, 274 byte
Pemakaian:
scala sandpile.scala <iterations>
Saya rasa tidak banyak yang bisa dijelaskan tentang ini. Pada dasarnya itu hanya menambahkan satu butir pasir ke tengah. Kemudian periksa apakah lebih besar dari 4, jika demikian itu akan tumpah dan memeriksa semua tetangga lebih besar dari 4, tumpah, dll. Ini cukup cepat.
Kinerja:
sumber
J, 76 byte
Saya mendefinisikan kata kerja
p
yang melapisi batas nol di sekitar input. Kata kerja utama mengambil array sebagai input. Kemudian memeriksa baris pertama untuk setiap tumpukan pasir yang berisi 4 atau lebih butir. Jika ada, itu menghasilkan array yang sama kecuali menggunakan empukp
, dan jika tidak melakukan konvolusi 2d untuk mensimulasikan jatuh butir. Kata kerja utama diulang sampai konvergensi menggunakan operator daya^:_
.Pemakaian
Diperlukan waktu sekitar 46 detik untuk menghitung hasil untuk n = 50000, dan hasilnya dapat ditampilkan menggunakan
viewmat
addon dengan skema warna monokrom.sumber
C 229 (dengan banyak peringatan)
sumber
APL (Dyalog Unicode) , 51 byte SBCS
Cobalah online!
sumber
PHP, 213 byte
secara rekursif membuat tumpukan
$p
, mengingat ukurannya$m
; kemudian mencetak dengan loop bersarang.Jalankan dengan
-r
.sumber