Perl, 92 90 89 84 byte
Termasuk +1 untuk -n
Beri ketinggian pada STDIN:
perl -M5.010 bolt.pl <<< 15
bolt.pl
:
#!/usr/bin/perl -n
map{$_=$;until$;=$_,s/.6|3.?/53|16*rand/eg,/3|6/>/36/;say y|3615|\\/ |r}(1x$_.6)x$_
Penjelasan
Jika Anda memanggil offset dari titik awal 0 (titik ada di sudut kotak karakter), maka pada baris berikutnya Anda dapat pergi ke kiri atau kanan (atau tidak) dan dapat berakhir dengan titik pada offset -1,1
. Baris berikutnya memberikan -2,0,2
kemungkinan offset dll. Mereka semua berbeda 2. Jika Anda kemudian memanggil karakter ke kiri bawah titik genap dan karakter ke kanan bawah ganjil, Anda dapat memperluas untuk menetapkan genap atau ganjil untuk setiap posisi karakter pada baris sedemikian rupa sehingga genap dan ganjil bergantian (sebenarnya seluruh bidang ubin dalam pola kotak-kotak). Posisi genap dapat memiliki /
atau
, posisi aneh dapat memiliki \
atau
.
Karakter tepat sebelum /
berada dalam posisi yang aneh sehingga bisa baik \
atau
, namun \/
dilarang sehingga hanya
dimungkinkan. Demikian pula karakter setelah a \
harus menjadi
(dengan asumsi baris diisi dengan cukup ruang ke kiri dan kanan sehingga batas-batas baris tidak ada masalah). Jadi petir berlanjut pada baris berikutnya selalu tepat di bawah a \
atau di bawah a /
. Dalam kedua kasus titik yang lebih rendah di tengah dan baris berikutnya dapat memiliki salah satu dari
, /
, \
atau /\
langsung di bawah bagian atas 2 karakter. Jadi untuk menghasilkan baris berikutnya saya cukup mengganti saja \
atau/
oleh salah satu dari 4 ekspansi ini dengan probabilitas yang sama (Anda juga bisa secara independen mengganti karakter pertama dengan
atau /
dan karakter kedua dengan
atau \
). Dalam perl Anda bisa melakukan ini dengan sesuatu seperti:
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
Jika baris yang dihasilkan namun mengandung \/
(dilarang bergabung) atau tidak ada /
atau \
sama sekali (baut mati dan tidak mencapai bagian bawah) hasilnya tidak valid. Dalam hal ini saya membuang seluruh baris dan coba lagi. Kelanjutan yang valid selalu ada dan jika Anda mencoba cukup sering akan ditemukan (mis. Semuanya mati kecuali untuk 1 aliran). Ini adalah distribusi probabilitas yang sedikit berbeda dari algoritma anti-overlap yang disarankan, tapi saya pikir ini sebenarnya lebih baik karena tidak memiliki bias arah. Validitas dapat diuji menggunakan cara golf
m#\\|/#>m#\\/#
Masalahnya di sini adalah bahwa substitusi acak begitu looooong dan semua \
lolos ini juga memakan byte. Jadi saya memutuskan untuk membuat baris saya menggunakan string angka dan mengganti digit yang sesuai
, /
dan \
sebelum mencetak. Penggantian acak dasar adalah
53|16*rand
yang memberikan salah satu 53
, 55
, 61
atau 63
dengan probabilitas yang sama. Saya kemudian menafsirkan 5
dan 1
sebagai
, 3
sebagai \
dan 6
sebagai /
. Itu menjelaskan cetak baris:
say y|3615|\\/ |r
Dalam kompetisi golf yang serius sekarang saya akan mulai mengeksplorasi formula sulap alternatif secara sistematis, tetapi ini seharusnya cukup bagus (dalam 3 byte optimal)
Sisa komponen program:
1x$_.6
Ini menginisialisasi $_
(lihat peta berikutnya) ke ruang ketinggian diikuti oleh a /
. Ini adalah baris tak terlihat di atas yang pertama dicetak dan memastikan bidang cukup lebar sehingga baut tidak pernah kehabisan ruang di sebelah kiri
map{ ... ; say ...}(1x$_.6)x$_
Saya akan memproses kali ini tinggi string awal yang sama mencetak baris baru setiap kali
$_=$;until$;=$_,...
Simpan baris saat ini di $;
. Jika penggantian ternyata pengembalian tidak valid $_
dari$;
s/.6|3.?/53|16*rand/eg
Lakukan penggantian yang sebenarnya. Saya tidak perlu memeriksa apa yang sebelum /
atau sesudah \
karena itu harus spasi. Ini nyaman karena ruang dapat diwakili oleh salah satu 1
atau 5
. Karena saya hanya mengisi string ke kiri setelah spasi \
masih bisa absen, jadi buat karakter itu opsional
/3|6/>/36/
Periksa apakah baris baru itu valid
Stay safe and have fun golfing!
Mungkin juga menentukan bahwa jika EAS menyerang, tinggalkan segalanya dan ikuti perintah! Kode golf bukan prioritas Anda dalam situasi seperti itu.