Python 3.5, 703 695 676 648 587 581 542 535 500 486 462 431 423 411 bajtów:
( Podziękowania dla @flawr za porady dotyczące oszczędzania 55 bajtów (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]))
Nie bardzo pretendent do tytułu, ale wciąż dałem mu szansę i działa idealnie. Z czasem będę starał się go skracać, ale na razie kocham to i nie mogę być szczęśliwszy.
Wypróbuj online! (Ideone) (Może wyglądać nieco inaczej z powodu widocznych ograniczeń kompilatora online. Jednak nadal jest bardzo podobny).
Wyjaśnienie:
Dla celów tego wyjaśnienia załóżmy, że powyższa funkcja została wykonana z wejściem r
, będąc równa 1
. To powiedziawszy, w zasadzie to, co się dzieje, krok po kroku, to ...
q=[*Z(R(0,B-1,2),R(B-1,0,-2))]
Obiekt zip q
jest tworzony z 2 obiektami zakresu, z których jeden składa się z co drugiej liczby całkowitej w zakresie, 0=>r+r+1
a drugi z co drugiej liczby całkowitej w zakresie r+r+1=>0
. Jest tak, ponieważ każdy początkowy wzór kreteńskiego labiryntu określonego stopnia zawsze będzie miał parzystą liczbę -
w każdej linii. Na przykład, w przypadku cretan labiryntu stopnia 1
, r+r+1
równa 3
, a tym samym jego wzór będzie zawsze zaczynają 0
kreskami, a następnie zgodnie z innym 4
(2 + 2) kresek. Ten obiekt zip zostanie użyty do pierwszych r+1
linii wzoru labiryntu.
Uwaga: tylko powodem q
jest lista i oddzielone od reszty jest ponieważ q
odwołuje się kilka razy i indeksowaną oraz zaoszczędzić dużo powtórzeń i pozwalają na indeksowanie, ja po prostu stworzony obiekt zip q
w formie listy.
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]))
To ostatni krok, w którym labirynt jest zbudowany i złożony. Tutaj trzy listy, pierwsza składająca się z górnych 4*r+1
linii labiryntu, druga składająca się ze środkowych 3*r+3
linii labiryntu, a ostatnia lista składająca się z ostatniej linii labiryntu są połączone razem, z podziałem linii ( \n
) na jeden długi sznurek. Na koniec wydrukowano ten jeden wielki sznurek składający się z całego labiryntu. Przyjrzyjmy się dokładniej, co faktycznie zawierają te dwie listy i 1 ciąg:
Pierwsza lista, w której inny obiekt spakowany jest używany do interpretacji listy, aby utworzyć każdą linię jeden po drugim, z wiodącymi |
lub +
symbolami, nieparzystą liczbą myślników w zakresie 0=>4*(r+1)
, końcowymi |
lub +
symbolami, a następnie nową linię ( \n
). W przypadku 1
labiryntu stopni ta lista zwraca:
+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
Druga lista, która składa się z obiektu zip zawierającego 4 listy, a każda lista odpowiada liczbie |
symboli wiodących / końcowych , liczbie +
symboli, liczbie myślników i wreszcie ostatniej liście, która zawiera pierwsze r+1
wiersze wzór utworzony według obiektu zip q
, linia pośrodku wzoru (ta bez |
) i ostatnie r+2
linie wzoru symetrycznego. W tym konkretnym przypadku ostatnia lista użyta w obiekcie zip tej listy zwróciłaby:
+ | | | +
--+ | +--
----+----
--+ | +--
+ | | | +
--+ | +-- <- Last line created especially for use in the middle of the labyrinth itself.
A zatem, w przypadku labiryntu 1 stopnia, cała lista powróciłaby:
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ | <- Here is where the extra line of the pattern is used.
Ta ostateczna lista, w której tworzony jest ostatni wiersz. Tutaj P
tworzony jest pierwszy segment (ten przed pierwszym spacją) długość ostatniego wiersza listy liczba spacji. Następnie dodaje się długość ostatniego segmentu (segmentu końcowego) tej samej linii + 4 liczby myślników, z których wszystkie są poprzedzone i poprzedzone pojedynczym +
symbolem. W przypadku labiryntu stopnia 1 ta ostatnia lista zwraca:
+---------------+
Po połączeniu tego wszystkiego razem ten krok w końcu zwraca ukończony labirynt. W przypadku labiryntu 1 stopnia w końcu zwróciłoby to:
+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ |
+---------------+
R=range
czy coś takiego? To samo dotyczyP='+'
?for g,o,k,u in Z