Perl, 92 90 89 84 byte
Bao gồm +1 cho -n
Cho chiều cao trên 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$_
Giải trình
Nếu bạn gọi phần bù của điểm bắt đầu 0 (một điểm nằm ở góc của hộp ký tự), thì ở hàng tiếp theo bạn có thể đi sang trái hoặc phải (hoặc không) và có thể kết thúc bằng điểm trên điểm bù -1,1
. Hàng tiếp theo cung cấp -2,0,2
khả năng bù trừ có thể, v.v ... Tất cả đều khác nhau bằng 2. Nếu sau đó bạn gọi ký tự ở phía dưới bên trái của một điểm chẵn và ký tự cho số lẻ bên phải phía dưới, bạn có thể mở rộng để gán chẵn hoặc lẻ cho từng vị trí ký tự trên một hàng sao cho xen kẽ và lẻ (trên thực tế toàn bộ mặt phẳng được lát theo mô hình bàn cờ). Một vị trí chẵn có thể có một /
hoặc
, một vị trí lẻ có thể có \
hoặc
.
Nhân vật ngay trước a /
đang ở một vị trí kỳ lạ nên có thể là \
hoặc
, nhưng \/
bị cấm nên chỉ
có thể. Tương tự, ký tự sau a \
phải là một
(giả sử hàng được đệm với đủ khoảng trắng ở bên trái và bên phải để ranh giới hàng không có vấn đề). Vì vậy, một tia sét tiếp tục ở hàng tiếp theo luôn trực tiếp bên dưới a \
hoặc bên dưới a /
. Trong cả hai trường hợp điểm thấp hơn là ở giữa và hàng tiếp theo có thể có một trong những
, /
, \
hoặc /\
trực tiếp dưới 2 ký tự đầu. Vì vậy, để tạo hàng tiếp theo, tôi chỉ cần thay thế bất kỳ \
hoặc/
bởi bất kỳ trong số 4 lần mở rộng này với xác suất bằng nhau (bạn cũng có thể thay thế độc lập ký tự đầu tiên bằng
hoặc /
và ký tự thứ hai bằng
hoặc \
). Trong perl bạn có thể làm điều này với một cái gì đó như:
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
Tuy nhiên, nếu hàng kết quả có chứa \/
(cấm tham gia) hoặc không /
hoặc hoàn \
toàn (bu lông chết và không chạm đáy) thì kết quả không hợp lệ. Trong trường hợp đó, tôi vứt bỏ toàn bộ hàng và chỉ cần thử lại. Tiếp tục hợp lệ luôn tồn tại và nếu bạn cố gắng thường xuyên sẽ tìm thấy đủ (ví dụ: mọi thứ đều chết trừ 1 luồng). Đây là một phân phối xác suất hơi khác so với thuật toán chống chồng chéo được đề xuất, nhưng tôi nghĩ rằng điều này thực tế tốt hơn vì nó không có sự thiên lệch hướng. Hiệu lực có thể được kiểm tra theo cách chơi golf
m#\\|/#>m#\\/#
Vấn đề ở đây là sự thay thế ngẫu nhiên rất looooong và tất cả những lần \
thoát này cũng ăn byte. Vì vậy, tôi quyết định xây dựng hàng của tôi sử dụng chuỗi các chữ số và thay thế các chữ số thích hợp bằng
, /
và \
ngay trước khi in. Sự thay thế ngẫu nhiên cơ bản là
53|16*rand
mang đến cho một trong những 53
, 55
, 61
hoặc 63
với xác suất bằng nhau. Sau đó tôi giải thích 5
và 1
như
, 3
như \
và 6
như /
. Điều đó giải thích việc in hàng:
say y|3615|\\/ |r
Trong một cuộc thi golf nghiêm túc, bây giờ tôi sẽ bắt đầu khám phá một cách có hệ thống các công thức ma thuật thay thế, nhưng điều này sẽ khá tốt (trong vòng 3 byte tối ưu)
Phần còn lại của các thành phần của chương trình:
1x$_.6
Điều này khởi tạo $_
(xem bản đồ tiếp theo) đến các không gian chiều cao theo sau là a /
. Đây là một hàng vô hình phía trên cái đầu tiên được in và đảm bảo trường đủ rộng để bu-lông không bao giờ hết chỗ trống ở bên trái
map{ ... ; say ...}(1x$_.6)x$_
Tôi sẽ xử lý lần này chiều cao chuỗi ban đầu tương tự in một hàng mới mỗi lần
$_=$;until$;=$_,...
Lưu hàng hiện tại vào $;
. Nếu thay thế hóa ra là khôi phục không hợp lệ $_
từ$;
s/.6|3.?/53|16*rand/eg
Làm thay thế thực tế. Tôi không phải kiểm tra những gì trước /
hoặc sau \
vì nó phải là một không gian. Đây là tiện lợi vì không gian có thể được đại diện bởi một trong hai 1
hoặc 5
. Vì tôi chỉ đệm chuỗi bên trái khoảng trống sau khi \
vẫn có thể vắng mặt, do đó, làm cho ký tự đó là tùy chọn
/3|6/>/36/
Kiểm tra xem hàng mới có hợp lệ không
Stay safe and have fun golfing!
Cũng có thể chỉ định rằng nếu EAS đình công, hãy từ bỏ mọi thứ và làm theo lệnh! Mã golf không phải là ưu tiên của bạn trong tình huống như vậy.