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
. Это, как говорится, в основном то, что происходит, шаг за шагом, это ...
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
в виде списка.
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-градусного лабиринта он, наконец, вернет это:
+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ |
+---------------+
R=range
или что-то в этом роде? То же самое дляP='+'
?for g,o,k,u in Z