Домохозяйство для Минотавра


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]))

Не очень много претендента на титул, но я все же дал ему шанс, и он работает отлично. Я постараюсь сократить его со временем, где смогу, но сейчас я люблю это и не могу быть счастливее.

Попробуйте онлайн! (Идеально) (Здесь может выглядеть немного по-другому из-за явных ограничений компилятора в сети. Однако, это все еще почти то же самое.)

Объяснение:

В целях этого объяснения, давайте предположим, что вышеупомянутая функция была выполнена с вводом, rравным 1. Это, как говорится, в основном то, что происходит, шаг за шагом, это ...

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

    Zip-объект, qсоздается с двумя объектами диапазона, один из которых состоит из каждого второго целого числа в диапазоне, 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 строка:

    • Первый список, в котором другой заархивированный объект используется в понимании списка для создания каждой строки одна за другой, с начальными |или +символами, нечетным числом тире в диапазоне 0=>4*(r+1), конечными |или +символами, а затем с новой строкой ( \n). В случае 1лабиринта степени этот список возвращает:

      +-----------------------------+
      | +-------------------------+ |
      | | +---------------------+ | |
      | | | +-----------------+ | | |
      | | | | +-------------+ | | | |
      | | | | | +---------+ | | | | |
      | | | | | | +-----+ | | | | | |
      | | | | | | | +-+ | | | | | | |
      
    • 2-й список, который состоит из zip-объекта, содержащего 4 списка, и каждый список соответствует числу начальных / конечных |символов, количеству +символов, количеству тире и, наконец, последнему списку, который содержит первые r+1строки образец, созданный согласно объекту почтового индекса 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.