Printing Comellas' labyrinth in python

labelinto-de-comellas.png

In a previous post (in Spanish), I mentioned Comellas' Labyrinth (shown in the above image). The image got fixed in my mind… so, I started wondering about generalizations of the labyrinth.

Firstly, I wanted to print the labyrinth. In the code block below the phrase would be "Diosestaentodaspartes", but would be introduced as a variable to the code.

phrase_len = len(phrase)
if phrase_len % 2 == 0:
    print(f"The phrase:\n{phrase}\nhas an even number of characters")
    print("Quiting the program")
    quit()
n = phrase_len // 2
for i in range(1,n+1):
    print(" "*(n-i+1), phrase[0:i], " "*(n), sep="")
print(phrase)
for i in range(n):
    print(" "*(n), phrase[i-n:], " "*(i+1), sep="")
          D          
         Di          
        Dio          
       Dios          
      Diose          
     Dioses          
    Diosest          
   Diosesta          
  Diosestae          
 Diosestaen          
Diosestaentodaspartes
          odaspartes 
          daspartes  
          aspartes   
          spartes    
          partes     
          artes      
          rtes       
          tes        
          es         
          s

Going beyond: changing the intersection

In the previous post we found that the number of ways to read the phrase was given by \(2\) powered to the number of steps to reach the hypotenuse of a triangle, multiplied by \(2\) to the number of steps to reach the other hypotenuse, i.e.

\begin{equation} \label{eq:1} \mathrm{ways} = 2^{10} \times 2^{10} = 2^{10 + 10} = 2^{20}. \end{equation}

NOTE that it is equal to \(2\) to the total number of steps.

Hence, the number of ways to read the phrase doesn't depend of the intersecting letter!

The code below changes the character of intersection:

def comellas_labyrinth(phrase:str, intersection=None):
    try:
        if not isinstance(phrase, str):
            raise TypeError(f"The phrase:\n{phrase}\nis of type {type(phrase)}, not a str")
        phrase_len = len(phrase)
        if phrase_len % 2 == 0:
            raise ValueError(f"The phrase:\n{phrase}\nhas an even number of characters")
        if (intersection is not None):
            if (not isinstance(intersection, int)):
                raise TypeError(f"The intersection variable: {intersection} is of type {type(intersection)}, not an int")
            if not (1 <= intersection <= phrase_len):
                raise ValueError(f"The value of intersection is out of range\nintersection value ranges between 1 and {len(phrase)}")
    except TypeError as t_error:
        print(f"TypeError found:\n{t_error}")
    except ValueError as v_error:
        print(f"ValueError found:\n{v_error}")
    else:
        n = phrase_len // 2
        if intersection:
            L, R = intersection - 1, 2 * n - intersection + 1
        else:
            L, R = n, n
        for i in range(1,L+1):
            print(" "*(L-i+1), phrase[0:i], " "*(R), sep="")
        print(phrase)
        for i in range(R):
            print(" "*(L), phrase[i-R:], " "*(i+1), sep="")

comellas_labyrinth("Diosestaentodaspartes", intersection=6)        
     D               
    Di               
   Dio               
  Dios               
 Diose               
Diosestaentodaspartes
     taentodaspartes 
     aentodaspartes  
     entodaspartes   
     ntodaspartes    
     todaspartes     
     odaspartes      
     daspartes       
     aspartes        
     spartes         
     partes          
     artes           
     rtes            
     tes             
     es              
     s

Author: Oscar Castillo-Felisola

Created: 2026-04-02 Thu 14:59