Kehidupan aneh sarang lebah

19

Para peneliti baru-baru ini menemukan koloni lebah yang menarik yang hidup di bidang sarang lebah yang tak terbatas:

Sarang madu

Setiap sel dapat menampung lebah atau tidak. Faktanya, kehidupan makhluk-makhluk itu tampak sedikit ... kacau. Dapat dihitung bahwa suatu koloni selalu dimulai dengan pola berikut:

Pola awal

(Lebah digambar oleh Emmanuel Boutet di Wikimedia Commons . Gambar sarang lebah dan lebah ini dirilis di bawah CC-By-SA . Menggerutu )

Setelah itu siklus hidup lebah dibagi menjadi beberapa generasi. Setiap generasi lebah tua mati dan yang baru menetas dan itu terutama tergantung pada tetangga sel mereka:

  • Jika seekor lebah memiliki kurang dari dua tetangga, ia mati karena kesepian.
  • Jika seekor lebah memiliki lebih dari tiga tetangga, ia mati karena kepadatan yang berlebihan.
  • Jika sel memiliki dua, tiga atau empat lebah hidup di sel tetangga, lebah baru menetas di sana pada generasi berikutnya.

Lebah yang sekarat tidak mati sampai akhir generasi sehingga mereka masih mempengaruhi sel-sel di sekitarnya yang mungkin menetas pada generasi berikutnya.

Sekarang kita tahu bagaimana koloni bekerja, kita dapat mensimulasikannya melalui beberapa generasi.

Memasukkan

Input adalah angka tunggal N , diberikan pada input standar, diakhiri oleh jeda baris. 0 ≤ N ≤ 150. Ini adalah jumlah generasi yang disimulasikan.

Keluaran

Output adalah angka tunggal, pada output standar dan secara opsional diikuti oleh satu baris break, yang mewakili jumlah lebah hidup setelah generasi N.

Output tambahan pada kesalahan standar diabaikan.

Input sampel

0
5
42
100

Output sampel

6
44
1029
5296

Kondisi menang

Kode terpendek menang, seperti kebiasaan dalam golf. Dalam kasus seri, solusi sebelumnya menang.

Uji kasus

Ada dua skrip pengujian, yang berisi kasus pengujian yang identik:

Doa dalam kedua kasus:, <test script> <my program> [arguments]misalnya ./test ruby beehive.rbatau ./test.ps1 ./beehive.exe.

Saya tahu hanya ada 22 tes, bukan 151 (terutama karena solusi sering sangat lambat). Harap jangan menyematkan kasus uji yang tepat alih-alih menyelesaikan tugas. Skrip ini adalah kemudahan bagi Anda untuk menguji apakah suatu perubahan masih menyebabkan program berperilaku dengan benar; bukan berarti Anda dapat menyesuaikan kode Anda dengan kasus uji tertentu.

Catatan lain

Tugas ini adalah bagian dari kontes golf yang diadakan di universitas saya selama 2011-W24. Nilai dan bahasa kontestan kami adalah sebagai berikut:

  • 336 - C
  • 363 - C
  • 387 - C
  • 389 - Haskell
  • 455 - C

Solusi kami sendiri adalah

  • 230 - Ruby
Joey
sumber
Ini terdengar seperti permainan kehidupan Conway.
Peter Olson
Tentu saja; itu sebabnya itu ditandai seperti itu juga. Ini sangat terselubung, memang.
Joey

Jawaban:

9

Ruby, 181 163 153 146 karakter

h=[0]*4e4
[0,-200,201,202,2,3].map{|i|h[i]=1}
gets.to_i.times{h=h.map{[g=1,200,201].map{|x|g+=h[x]+h[-x]};g>5-h.rotate![-1]||g<3?0:1}}
p h.count 1

Implementasi ini mengikuti pendekatan standar menggunakan array h(dimensi 200x 200diratakan), di mana setiap elemen dapat berupa 0(tidak ada lebah) atau 1(termasuk lebah). Array [0,-200,201,202,2,3]menggambarkan posisi awal lebah (relatif terhadap sel awal apa pun).

Input dan output seperti yang ditentukan di atas, melewati semua kasus uji yang ditentukan.

Sunting 1: diubah kembali ke solusi pembungkus alih-alih versi "ruang tambahan" (yang lebih pendek dalam versi perantara tetapi sekarang beberapa karakter lebih panjang).

Sunting 2: variabel dihapus bsepenuhnya.

Sunting 3: peringatan: suntingan ini membuat program sangat lambat. Dengan demikian saya mengurangi dimensi menjadi 200 masing-masing yang masih cukup untuk hingga 150 iterasi. Alih-alih mengindeks array dengan variabel, kami terus-menerus memutar array ke depan. Desainnya tidak terlalu bagus, tapi sekarang kita jauh di bawah 150.

Howard
sumber
7

Python, 152 karakter

P=[0,2,3,1j,1+1j,1-1j]
for i in' '*input():Q=[p+d for d in(1,-1,1j,-1j,1j-1,1-1j)for p in P];P=set(p for p in Q if 1<Q.count(p)<5-(p in P))
print len(P)

Solusi ini melacak lokasi lebah dengan sejumlah bilangan kompleks. Ini sangat lambat karena loop bagian dalam kuadratik dalam jumlah lebah. Saya sudah menguji hingga 50 dan berhasil.

Keith Randall
sumber
Python2.7 telah menetapkan pemahaman
gnibbler
Saya berpikir untuk melacak lebah, tetapi melakukannya dengan bilangan kompleks seperti itu benar-benar rapi! Anda juga dapat menyimpan 3 karakter dengan mengganti for loop dengan exec (seperti yang saya lakukan).
Jules Olléon
Python2.7 juga telah menetapkan literal, sehingga Anda dapat menulis P={0,2,3,1j,1+1j,1-1j}dan kemudian menggunakan {p}<Puntuk menguji keanggotaan (menghemat 1 char)
gnibbler
5

Python, 171 169 158 karakter

w=300
s=w*w
x=[0]*297
h=[1,1,0]+x+[1,0,1,1]+x+[1]+x*s
exec('h=[1<sum(h[(i+x)%s]for x in[-1,-w-1,-w,1,w+1,w])<5-h[i]for i in range(s)];'*input())
print sum(h)

Saya memodelkan dunia sebagai array 300 * 300 = 900000 1D ( hsebenarnya lebih besar, tetapi akhirnya tidak digunakan), di mana lebah adalah 1 dan kosong adalah 0. Ukuran 300 baik-baik saja karena paling banyak pertumbuhan akan dari 2 di setiap dimensi untuk setiap generasi, dan tidak ada lebih dari 150 generasi.

Ini adalah versi yang sedikit tidak dikomentari dan dikomentari:

w=300 # width and height of the world
s=w*w
# create initial grid
l=[1,1]+[0]*298+[1,0,1,1]+[0]*297+[1]+[0]*s

for k in range(input()):
  h=l[:]

  for i in range(s):

    # for each point, compute the number of neighbors
    n=sum(map(lambda x:h[(i+x)%s],[-1,-w-1,-w,1,w+1,w]))

    # if that number verifies the conditions, put 1 here, if not put 0
    l[i]=1<n<5-h[i]

print sum(l)
Jules Olléon
sumber