Perl, 92 90 89 84 байт
Включає +1 для -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$_
Пояснення
Якщо ви називаєте зсув початкової точки 0 (точка знаходиться в куті поля символів), то в наступному рядку ви можете піти вліво або вправо (або ні), і в кінцевому підсумку можуть бути точки на зміщення -1,1. Наступний рядок дає -2,0,2можливі зрушення і т. Д. Усі вони відрізняються на 2. Якщо ви зателефонуєте символу в нижній лівій частині точки і символу в нижній правій непарній, ви можете розширити його до присвоєння парного або непарного для кожної позиції символу на такий ряд, що парні і непарні чергуються (адже вся площина викладена плиткою у шаблоні). Положення навіть може мати /або непарне положення може мати \або .
Персонаж безпосередньо перед a /знаходиться в непарному положенні, тому він може бути \або , але \/заборонений, тому тільки можливий. Аналогічно, символ після \ must- a повинен бути (якщо припустити, що рядок є достатньо пробілів ліворуч та праворуч, так що межі рядків не є проблемою). Таким чином, блискавка продовжується в наступному ряді завжди безпосередньо під a \або нижче a /. У будь-якому випадку нижня точка знаходиться в середині , і наступний рядок може мати один з , /, \або /\безпосередньо під верхні 2 символів. Отже, щоб створити наступний рядок, я можу просто замінити будь-який \або/будь-яким із цих 4 розширень з однаковою ймовірністю (ви також можете самостійно замінити перший символ на або, /а другий символ на або \). В perl ви можете зробити це з чимось на зразок:
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
Якщо рядок, що виходить, містить \/(заборонено з'єднання) або взагалі немає /або \взагалі (болт гине і не доходить до нижньої частини), результат недійсний. У такому випадку я викидаю весь ряд і просто намагаюся знову. Дійсне продовження завжди існує, і якщо ви будете намагатися досить часто, його знайдемо (наприклад, все вмирає, крім 1 потоку). Це дещо інший розподіл ймовірностей від запропонованого алгоритму проти накладення, але я думаю, що це насправді краще, оскільки він не має спрямованого зміщення. Дійсність може бути перевірена гольф-способом, використовуючи
m#\\|/#>m#\\/#
Проблема тут полягає в тому, що випадкова заміна настільки сильна і всі ці \втечі також їдять байти. Тому я вирішив створити свої рядки за допомогою рядків цифр і замінити відповідні цифри на , /і \безпосередньо перед друком. Основна випадкова заміна - це
53|16*rand
який дає один з 53, 55, 61або 63з однаковою ймовірністю. Потім я інтерпретую 5і 1як , 3як \і 6як /. Це пояснює друк рядків:
say y|3615|\\/ |r
У серйозних змаганнях з гольфу я б зараз почав систематично досліджувати альтернативні магічні формули, але це повинно бути досить непогано (в межах 3 байт оптимального)
Решта компонентів програми:
1x$_.6
Це ініціалізує $_(див. Наступну карту) на проміжки висот, а потім a /. Це невидимий рядок над першим надрукованим і гарантує, що поле є достатньо широким, щоб у болта ніколи не було місця зліва
map{ ... ; say ...}(1x$_.6)x$_
Я обробляю цю саму початкову висоту рядків раз, друкуючи новий рядок кожен раз
$_=$;until$;=$_,...
Збережіть поточний рядок у $;. Якщо заміна виявиться недійсною, відновлення $_з$;
s/.6|3.?/53|16*rand/eg
Зробіть фактичну підміну. Мені не потрібно перевіряти, що є до /чи після, \оскільки це повинно бути пробіл. Це зручно, оскільки простір може бути представлений 1або 5. Оскільки я лише проклав рядок ліворуч, пробіл після цього \ще може бути відсутнім, тому зробіть цей символ необов’язковим
/3|6/>/36/
Перевірте, чи дійсний новий рядок
Stay safe and have fun golfing!Можливо, також уточнюйте, що якщо EAS завдає удару, відмовтесь від усього і виконайте замовлення! Гольф-код не є вашим пріоритетом у такій ситуації.