Ураган Метью та блискавки


27

Виклик

Натхнені цим викликом і неприємним ураганом Метью , ми будемо динамічно створювати кілька блискавок.

n = 15:

   \
   /\
  /  \
 /   /
/\  /\
 /  \ \
/   / /\
   /\ \
  / /  \
 /\ \  /\
  /  \ \
 /\  /  
   \
    \
    /\

Вхідні дані

Позитивний цілий номер nвизначає глибину блискавки.

Правила та обмеження

  • /і \слід використовувати
  • Ймовірність направлення блискавки така:
    • 25% Розбивається на 2 доріжки
    • 25% Шлях доходить у глухий кут
    • 25% йде ліворуч
    • 25% йде правильно
    • Нижче наведено кілька винятків щодо перекриття та глухого кута:
  • Код не повинен бути детермінованим, кожен раз, коли кожен блискавка повинен генеруватися випадковим чином
  • Болти не повинні перекриватися: наприклад, якщо вже є болт ліворуч від поточного болта, то струм болта повинен або закінчуватися, або йти праворуч, але не йти ліворуч або розщеплюватися (ймовірність все-таки діє, в цьому випадку він стає на 50% кінцем / 50% право)
  • Якщо не існує іншого доступного розділеного шляху, шлях не повинен закінчуватися: наприклад, на початку, коли існує лише 1 шлях, шлях не повинен закінчуватися, поки він не розщепить, також застосовується, коли існує кілька шляхів, але всі, крім одного шляху, мертві , (ймовірність стає 33% роздвоєною / 33% зліва / 33% правою), ваша мета - досягти нижньої частини
  • Білі простори можна додати зліва (все, що вам знадобиться, має бути лише висотою-1)
  • Однак ви хочете генерувати болт саме вам, ви можете переходити знизу вгору, зліва направо і т.д.

Ще один приклад

n = 10

 \
 /
 \
 /\
  /\
 / /
/\ \
 / /\
 \   \
 /

Ураган Метью, мабуть, стріляє червоними болтами в небо, звані спрайтами

Будьте в безпеці та отримуйте задоволення від гольфу! Будьте відповідальні за гольф лише тоді, коли ви знаходитесь у безпечній зоні !!


7
Stay safe and have fun golfing!Можливо, також уточнюйте, що якщо EAS завдає удару, відмовтесь від усього і виконайте замовлення! Гольф-код не є вашим пріоритетом у такій ситуації.
— Ерік Аутгольфер

17
@EriktheGolfer Ви тоді не справжній гольфіст.
— Блакитний

4
Я не вірю, що "Найбільш центральний шлях повинен бути той, хто доходить до землі" відповідає решті опису випадкових поколінь. Наприклад, випадково можливо, щоб оригінальний болт роздвоєний двічі, а потім, щоб середні два болта закінчилися; як можна скасувати таку можливість, зберігаючи вказані ймовірності?
— Грег Мартін

Крім того, що станеться, якщо (наприклад, перші два кроки обидва розбиваються? Потім середні два болта торкаються один одного, що здається проблематичним, але також не виключається особливими випадками.
— Грег Мартін

@GregMartin Добре в центрі більшої частини, спочатку я сподівався, що він створить врівноважений болт, але тепер, коли я думаю про це навіть без цього обмеження, приблизно 50% часу він повинен закінчитися десь посередині, глибина з 15 мав би шанс на 1-2% лише там, де розташована права або ліва частина більшої стежки. Я вилучу це правило. А для розділення частини, що розділяється на 2 етапи, єдине, що слід запобігти, - це те, що жодна 2 контура не повинна з'єднувати 2 контури: \/у будь-якій точці.
— Зукаберг

Відповіді:


6

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/

Перевірте, чи дійсний новий рядок


+1 Охайно! Ви повинні включити цей інтернет-тестер perl -M5.010 main.pl <<< 25 , я отримав кілька приємних результатів!
— Зукаберг

Розумієте трохи пояснити, як це працює? Мені дуже весело генерувати їх ха-ха, я, чесно кажучи, не очікував таких хороших результатів.
— Зукаберг

На жаль, вам потрібно додати 3 байти-n , тому що простір та тире також враховуються. Це ж правило стосується аргументів командного рядка. Див. "Спеціальні виклики", друга точка: Я вважаю їх різницею підрахунку символів до найкоротшого еквівалентного виклику без них.
— Ерік Аутгольфер

1
@EriktheGolfer Ні, +1 - це нормально, оскільки ця програма прекрасно працює з командного рядка, за допомогою -nEякого лише на 1 символ більше -E(див. Статтю, на яку ви посилаєтесь. Це також позбавляється від потреби -M5.010) Я завжди представляю свій код як файли, оскільки це Це зручніше, але я завжди вважаю такі параметри: Якщо це можна запустити з командного рядка, я не рахую пробіл та тире. Якщо він повинен бути в файлі (наприклад , тому що він використовує do$0) я зробити порахувати простір і тире
— Ton Hospel

@TonHospel О, я не знав, що ти використовуєш -E. Якщо так, то ви добрі.
— Ерік Аутгольфер

0

JavaScript (ES6), 154 байти

f=(n,r=[],s=" ".repeat(n)+"/",t=s.replace(/ \/|\\ |\\$/g,_=>"  /  \\/\\".substr(Math.random()*8&6,2)))=>n?/^ +$|\\\//.test(t)?f(n,r,s):f(n-1,[...r,t],t):r
<input type="number" min=1 oninput=o.textContent=f(this.value).join`\n`><pre id=o>

Я боровся з реалізацією, поки не побачив відповідь @ TonHospel, і в цей момент він просто переродився в порт. Вибірка зразка:

         /\
        / /\
       /\   \
        /\   \
         /\  /
          / /\
         / / /\
            / /\
            \   \
             \
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.