Tanda panah Game of Life

26

Latar Belakang

Tantangan ini untuk menghormati apsillers , yang memenangkan kategori Tidak semudah kelihatannya di Best of PPCG 2016 dengan tantangan mereka. Dapatkah kotak musik 4-note saya memainkan lagu itu? Selamat!

Pada halaman "Tentang Saya", pengguna ini memiliki simulator yang sangat rapi untuk otomat seluler Game of Life . (Serius, pergi memeriksanya.) Di sisi lain, kata aspillera adalah bahasa Spanyol untuk "arrowslit". Mengingat fakta-fakta ini, tantangan ini adalah tentang panah di Game of Life.

Tanda panah Game of Life

Di GoL, kami akan mewakili panah oleh glider , dan dinding dengan urutan blok . Sebuah glider tunggal mendekati dinding dari atas, dan mencoba terbang melalui celah di dinding (tanda panah). Tugas Anda adalah untuk memeriksa apakah glider melewati tanda panah atau menabrak dinding.

Memasukkan

Input Anda adalah kisi bit, yang mewakili konfigurasi GoL. Anda dapat mengambilnya dalam format apa pun yang wajar (string multiline dari dua karakter ASCII yang dapat dicetak, daftar string, array 2D integer, array 2D boolean, dll.). Untuk kejelasan, saya akan menggunakan string multiline dari karakter .#berikut ini.

Input dijamin memiliki beberapa properti. Pertama, tingginya 2N untuk beberapa N ≥ 6 , dan lebarnya setidaknya 2N + 2 . Inputnya adalah semua .s, kecuali bahwa di suatu tempat di tiga baris teratas adalah glider, dan pada dua baris tengah ada dinding balok. Glider akan menuju barat daya atau tenggara, dan posisinya sedemikian rupa sehingga jika dinding dihilangkan, ia tidak akan melewati tepi samping sebelum mencapai tepi bawah (tetapi mungkin mencapai sudut kisi). Glider pada awalnya dipisahkan dari tepi kiri dan kanan setidaknya satu langkah .s. Itu bisa dalam fase apa pun.

Dinding terdiri dari blok, yang dipisahkan oleh satu kolom .s, kecuali di satu tempat, di mana mereka akan dipisahkan oleh setidaknya dua kolom .s. Seperti halnya glider, blok paling kiri dan paling kanan juga dipisahkan dari tepi dengan satu langkah .s. Akan selalu ada setidaknya satu blok di tepi kiri dan satu blok di tepi kanan.

Berikut adalah contoh dari kisi masukan yang valid:

....#......................
..#.#......................
...##......................
...........................
...........................
...........................
.##.##............##.##.##.
.##.##............##.##.##.
...........................
...........................
...........................
...........................
...........................
...........................

Keluaran

Seperti yang dinyatakan, tugas Anda adalah menentukan apakah glider menabrak dinding atau membuatnya sampai ke tepi selatan. Untuk keperluan tantangan ini, crash terjadi jika konfigurasi tidak lagi terdiri dari satu glider dan dinding blok, terlepas dari apa yang terjadi kemudian dalam simulasi. Diagram berikut menunjukkan celah terkecil yang dapat dilalui glider tenggara tanpa menabrak dalam dua fase yang berbeda (kondisi untuk glider barat daya simetris).

...#...........
.#.#...........
..##...........
...............
...............
##...........##
##...........##

...#...........
....#..........
..###..........
...............
...............
##...........##
##...........##

Jika glider terbang melalui dinding, Anda harus menampilkan nilai kebenaran, dan jika tidak, nilai palsu. Untuk contoh di atas, output yang benar adalah falsy, karena glider akan menabrak bagian kiri dinding.

Untuk keperluan tantangan ini, Anda dapat mengasumsikan bahwa jika Anda mensimulasikan GoL pada input untuk 2 * (tinggi - 3) langkah, glider berada di baris paling bawah di posisi yang diharapkan dan dinding masih utuh, maka hasilnya benar. .

Aturan dan penilaian

Anda dapat menulis program atau fungsi lengkap. Hitungan byte terendah menang.

Uji kasus

Saya telah mengumpulkan test case ke dalam repositori GitHub , karena mereka cukup besar. Berikut ini tautan ke masing-masing file:

Zgarb
sumber
Apakah ada alasan untuk memasukkan baris kosong di bawah dinding dalam input?
Martin Ender
@ MartinEnder Mereka membuat solusi di mana Anda benar-benar mensimulasikan GoL pada input yang lebih layak (setidaknya saya harap begitu).
Zgarb
Glider akan selalu dimulai di baris paling atas?
Rod
@ Ya Ya, itu akan berada di baris paling atas menuju barat daya atau tenggara.
Zgarb
Game lain dalam kehidupan: P
Christopher

Jawaban:

15

Python 2 , 142 136 135 byte

-6 byte terima kasih kepada ElPedro
-1 byte terima kasih kepada TuukkaX

p=input()
z=p[2].index(1)
m=(p[1][z]-p[1][z+1]<1)*2-1
k=i=0
for b in p[3:]:x=p[2][::m].index(1)+i;k|=1in b[::m][x-2:x+8];i+=1
print 1-k

Cobalah online! atau Verifikasi semua kasus uji

Memeriksa orientasi (timur / barat):

west_east
Menggunakan z=p[2].index(1)untuk mendapatkan kotak pertama di baris ke-3 (diwakili oleh kotak merah), dan kemudian m=(p[1][z]-p[1][z+1]<1)*2-1untuk mengurangi nilai di sebelah kanan (hijau) dari yang di sebelah kiri (biru), dengan cara ini semua 4 negara glider yang akan hasil barat daya 1(baris atas pada gambar), sedangkan yang ke tenggara menghasilkan 0atau -1.
Kemudian konversikan: 1 -> -1dan 0,-1 -> 1untuk digunakan pada parameter untuk membalik daftar ketika berhadapan dengan yang barat. Dengan cara ini, peluncur yang menuju barat daya dirundukkan sama dengan yang meluncur ke tenggara.

Gerakan peluncur

meluncur
Ini adalah gerakan yang dilakukan peluncur ke tenggara, ia memiliki pola "tangga", dan blok paling kiri di garis ke-3 konstan untuk setiap pola. Menggunakannya sebagai titik awal, 3 blok di sebelah kiri dan kanan, dan 4 blok tengah diperiksa untuk keberadaan 1s (yang akan menjadi dinding).
tanda panah
arrowslits_path

tongkat
sumber
Saya pikir Anda bisa kehilangan 4 byte dengan mengatur variabel ike 0luar forloop kemudian menambahkan 1 untuk itu setiap pass dan singkirkan enumerate. Tampaknya bekerja ketika saya mencobanya dengan TIO Anda. Memberi +1 untuk jawaban keren apakah saya benar atau salah.
ElPedro
Bagus! Anda dapat menyimpan byte dengan menghapus spasi 1 in. +1.
Yytsi
2
+1 untuk "weast"
JungHwan Min
4

Oktaf, 123 122 108 byte

Berkat @LuisMendo, tersimpan 2 byte

B=A=input("");B(1:3,:)=0;do;until nnz((A=A&(s=conv2(A,(m=-1:1)|m','same'))>1&s<4|~A&s==3)-B)-5;any(A(end,:))

Cobalah online!

Atau

Verifikasi semua kasus uji

Terima kasih kepada Rod menyiapkan kasus uji.

B=A=input("");
B(1:3,:)=0;
do
until nnz((A=A&(s=conv2(A,(m=-1:1)|m','same'))>1&s<4|~A&s==3)-B)-5
any(A(end,:))

Jawaban sebelumnya:

B=A=input("");
B(1:3,:)=0;
while nnz(A~=B)==5
    s=conv2(A,(m=-1:1)|m','same');
    x=~A;
    A&=~A|~(s<2|s>3);
    A|=x&s==3;
end;
any(A(end,:))

Ekstrak dulu pola dinding sebagai variabel B.
Lakukan simulasi GoL hingga pola dinding dan pola simulasi memiliki lebih / kurang dari 5 sel yang berbeda.
Jika glider telah menerima baris terakhir, fungsi mengembalikan true.

rahnema1
sumber
1
sampai pola dinding dan pola simulasi memiliki lebih / kurang dari 5 sel yang berbeda. Itu pintar!
Luis Mendo
@LuisMendo Terima kasih, menyelamatkan byted
rahnema1
3

Retina , 101 93 91 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1.

O$#^`.(?=(.*¶)*(?<=#_.\2.+##.(.*¶)\D+))
$#1
¶(?>_(_)*#+_+¶_+¶(?<1>_+¶)*)(?>(?<-1>.)+)_{11}

Cobalah online!

Tentu belum optimal.

Martin Ender
sumber