Поліпшення будинку для Мінотавра


42

Поліпшення будинку для Мінотавра

Критський лабіринт намалювати досить просто. Почніть тільки з симетричної форми (тут червоного кольору). Назвемо всі кінцеві точки цих рядків «вузлами». Потім ви починаєте малювати арки (чорні): Перший завжди починається у верхньому середньому вузлі та підключається до вузла поруч з ним з правого боку, потім з'єднуються два вузли, найближчі до попередньої арки. Це повторюється, поки всі вузли не охоплені.

gif

Тепер ми можемо узагальнити це поняття: ми можемо легко генерувати нові початкові візерунки, додаючи більше Lформ. Я перерахував початкові фігури наступним чином:

ступінь

Найбільш лівий візерунок створить критський лабіринт ступеня 0 . Наступний створить критський лабіринт 1 ступеня (оригінал) тощо.

Завдання

Враховуючи невід'ємне ціле число n, ваша програма повинна вивести уявлення ascii критського лабіринту ступеня n, що показано в наступних прикладах. Пробіли / нові рядки не мають значення. Ви повинні включити коротке пояснення того, як працює ваш код.

Приклади

Вихід для оригінального критського лабіриту (ступінь 1) наступний:

+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ |
              +---------------+

Початковий зразок:

+ | | | +
--+ | +--
----+----
--+ | +--
+ | | | +

Креатичний лабіринт 0 ступеня повинен виглядати так:

+-------------+ 
| +---------+ | 
| | +-----+ | | 
| | | +-+ | | | 
| | + | + | | | 
| +---+---+ | | 
+---+ | +---+ | 
      +-------+ 

Початковий зразок:

+ | +
--+--
+ | +

Відповіді:


10

Perl 5, 349 байт

say$p="| "x$_,"+","-"x(16*$n-4*$_+13),"+ $p"for 0..4*($n=pop)+3;say$p="| "x(3*$n+2),"+ | ","| "x2x$n,"+ $p|";$p=~s/..//,$q="-"x(4*$_-1),say"$p+$q+ ","| "x(2*$n-2*$_+1),"+$q+ $p|"for 1..$n;$p=~s/..//;say$p,("+---"."-"x4x$n)x2,"+ $p|";$p=~s/..//,$q="-"x(4*$n+3)."-"x4x$_,say"$p+$q+ | ","| "x2x($n-abs$_),"+$q+ $p|"for-$n..$n;say" "x(8*$n+6),"+----$q+"

(Передайте n як аргумент командного рядка.)

Обчислює лабіринт по черзі в шести розділах:

  • перші 4n + 4 рядки,
  • наступний рядок (єдиний рядок без -),
  • наступні n рядків,
  • наступний рядок (рядок посередині початкового шаблону),
  • наступні 2n + 1 рядки,
  • заключна лінія (рядок із провідними пробілами).

6

Python 3.5, 703 695 676 648 587 581 542 535 500 486 462 431 423 411 байт:

( Дякую @flawr за пораду щодо збереження 55 байт (486 -> 431)! )

def j(r):R=range;Z=zip;B=r+r+2;P,M='+-';X='| ';q=[*Z(R(0,B-1,2),R(B-1,0,-2))];L=r+1;A=2+r;print('\n'.join([X*w+P+M*v+P+' |'*w for v,w in Z(R(4*L*4-3,0,-4),R(4*L))]+[X*g+P*o+M*k+u+M*k+P*o+' |'*-~g for g,o,k,u in Z([*R(4*L-A,0,-1),*R(4*L-A)],[0]+[1]*(3*r+2),[0,*R(1,4*L,2),*R(4*L+1,11*r,2)],[M*y+'+ '+X*b+P+M*y for y,b in q]+[M*B+P+M*B]+[M*y+'+ '+X*b+P+M*y for y,b in q[::-1]+q[1:]])]+[' '*(8*r+6)+P+M*(8*r+7)+P]))

Не дуже багато претендента на титул, але я все-таки дав йому удар, і він працює чудово. Я спробую з часом її скоротити більше, де можу, але наразі це люблю і не могло бути щасливішим.

Спробуйте в Інтернеті! (Ideone) (Може виглядати дещо інакше тут через очевидних обмежень онлайн-компілятора. Однак це все ще дуже те саме.)

Пояснення:

Для цілей цього пояснення припустимо, що вищевказана функція виконувалась із введенням r, що дорівнює 1. Як говориться, в основному те, що відбувається, крок за кроком, це ...

  1. q=[*Z(R(0,B-1,2),R(B-1,0,-2))]

    Об'єкт zip, qстворюється з 2 об'єктів діапазону, один складається з кожного другого цілого числа в діапазоні, 0=>r+r+1а інший складається з кожного другого цілого числа в діапазоні r+r+1=>0. Це тому, що кожен вихідний зразок критського лабіринту певного ступеня завжди матиме парне число -у кожному рядку. Наприклад, для критського лабіринту ступеня 1, r+r+1так само 3, і , таким чином, його картина буде завжди починатися з 0тиром, а потім іншою лінією з 4(2 + 2) рисками. Цей об'єкт zip буде використовуватися для перших r+1рядків візерунка лабіринту.

    Примітка . Єдина причина q- це список і відокремлений від решти, тому що на qнього посилаються кілька разів і підписані, і щоб зберегти багато повторень і дозволити підписку, я просто створив zip-об’єкт qу вигляді списку.

  2. print('\n'.join([X*w+P+M*v+P+' |'*w for v,w in Z(R(4*L*4-3,0,-4),R(4*L))]+[X*g+P*o+M*k+u+M*k+P*o+' |'*-~g for g,o,k,u in Z([*R(4*L-A,0,-1),*R(4*L-A)],[0]+[1]*(3*r+2),[0,*R(1,4*L,2),*R(4*L+1,11*r,2)],[M*y+'+ '+X*b+P+M*y for y,b in q]+[M*B+P+M*B]+[M*y+'+ '+X*b+P+M*y for y,b in q[::-1]+q[1:]])]+[' '*(8*r+6)+P+M*(8*r+7)+P]))

    Це останній крок, на якому лабіринт будують і складають разом. Тут три списки, перший складається з верхніх 4*r+1ліній лабіринту, другий складається з середніх 3*r+3ліній лабіринту, і останній список, що складається з самого останнього рядка лабіринту, з’єднуються разом з розривами рядків ( \n) у одна довга струна Нарешті, ця величезна струна, що складається з усього лабіринту, роздрукована. Давайте детальніше розберемося, що насправді містять ці 2 списки та 1 рядок:

    • 1-й список, в якому інший об'єкт-блискавка використовується в розумінні списку для створення кожного рядка один за одним, із провідними |або +символами, непарною кількістю тире в діапазоні 0=>4*(r+1), проміжком |або +символами, а потім новим рядком ( \n). У разі 1лабіринту ступеня цей список повертає:

      +-----------------------------+
      | +-------------------------+ |
      | | +---------------------+ | |
      | | | +-----------------+ | | |
      | | | | +-------------+ | | | |
      | | | | | +---------+ | | | | |
      | | | | | | +-----+ | | | | | |
      | | | | | | | +-+ | | | | | | |
      
    • 2-й список, який складається з об'єкта zip, що містить 4 списки, і кожен список відповідає кількості провідних / кінцевих |символів, кількості +символів, кількості тире і, нарешті, останньому списку, який містить перші r+1рядки візерунок, створений відповідно до об'єкта zip q, лінії посередині візерунка (тієї, що немає |), і останні r+2рядки симетричного малюнка. У цьому конкретному випадку останній список, використаний у zip-об'єкті цього списку, поверне:

      + | | | +
      --+ | +--
      ----+----
      --+ | +-- 
      + | | | + 
      --+ | +--  <- Last line created especially for use in the middle of the labyrinth itself.
      

      І тому, у випадку лабіринту 1 ступеня, весь цей список повертається:

      | | | | | + | | | + | | | | | |
      | | | | +---+ | +---+ | | | | |
      | | | +-------+-------+ | | | |
      | | +-------+ | +-------+ | | |
      | +-------+ | | | +-------+ | |
      +-----------+ | +-----------+ | <- Here is where the extra line of the pattern is used.
      
    • Цей підсумковий список, в якому створюється останній рядок. Тут Pстворюється перший сегмент (той, що знаходиться перед першим пробілом), довжина останнього рядка списку пробілів. Потім додається довжина останнього відрізка (закінчуючий відрізок) того ж рядка + 4 числа тире, всі з яких передують і супроводжуються одним +символом. У разі лабіринту ступеня 1 цей останній список повертає:

                    +---------------+
      

    Після об'єднання всього цього разом цей крок, нарешті, повертає завершений лабіринт. У випадку лабіринту 1 ступеня, це нарешті поверне:

    +-----------------------------+
    | +-------------------------+ |
    | | +---------------------+ | |
    | | | +-----------------+ | | |
    | | | | +-------------+ | | | |
    | | | | | +---------+ | | | | |
    | | | | | | +-----+ | | | | | |
    | | | | | | | +-+ | | | | | | |
    | | | | | + | | | + | | | | | |
    | | | | +---+ | +---+ | | | | |
    | | | +-------+-------+ | | | |
    | | +-------+ | +-------+ | | |
    | +-------+ | | | +-------+ | |
    +-----------+ | +-----------+ |
                  +---------------+
    

1
Чи можете ви спочатку визначитись R=rangeчи щось подібне? Те саме для P='+'?
flawr

1
Я думаю, вам слід скористатися золотою нагодою, щоб сказатиfor g,o,k,u in Z
Sherlock9,

@ Шерлок9 Ха-ха! Гарна ідея! Додано. :)
Р. Кап
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.