Necesito hacer un patrón de triángulo de triángulo de * dependiendo de la entrada de entero.
Por ejemplo:
n = 2 * *** * * * *********n = 3 * *** ***** * * * *** *** *** *************** * * * * * *** *** *** *** *** *************************Ya descubrí el código para un solo triángulo, pero no sé cómo duplicarlos para que aparezcan como un triángulo de triángulos.
Aquí está mi código para un triángulo:
rows = int(input()) for i in range(rows): for j in range(i, rows): print(" ", end="") for j in range(i): print("*", end="") for j in range(i + 1): print("*", end="") print()He simplificado el siguiente código, por lo que ahora debería verse más claro y fácil de entender de lo que solía ser.
n = int(input("n = ")) rows = n ** 2 base = n * 2 - 1 for row in range(rows): triangle = row // n level = row % n a_space = " " * (n - triangle - 1) * base b_space = " " * (n - level - 1) line = (a_space + (b_space + "*" * (level * 2 + 1) + b_space) * (triangle * 2 + 1)).rstrip() print(line)Este enfoque imprime todo en una sola pasada. En la siguiente explicación, desglosaré los componentes del código, qué significan estas variables y cómo funcionan.
La primera variable que debo mencionar es n , el número de niveles o la altura de cada triángulo. También es el número de triángulos apilados unos encima de otros.
La segunda variable es rows , el número de filas en la salida. Podemos ver un patrón en el que el número de filas es igual a n al cuadrado.
La siguiente variable es base . Es el número de asteriscos en el nivel inferior del triángulo. También sigue un patrón de números impares como podemos haber notado.
Después de eso, nuestro ciclo comienza, itera a través de cada fila e imprime el resultado.
Estas variables nos dicen en qué triángulo y nivel del triángulo nos encontramos actualmente. Puede probarlo usted mismo imprimiendo un triangle y level cada iteración.
for row in range(rows): triangle = row // n level = row % n print(triangle, level) La siguiente parte es la sangría. Solo para darle una breve idea de lo que son a_space y b_space , aquí hay una representación visual que describe los espacios.
a_space reduce después de cada triángulo y b_space reduce después de cada nivel.
a_space = " " * (n - triangle - 1) * base b_space = " " * (n - level - 1) Multiplicamos a_space por base porque un a_space tiene una longitud igual a la base.
Veámoslo paso a paso.
- Primero, comenzamos nuestra línea con
a_space.a_space
- Luego, imprimimos los asteriscos. El número de asteriscos sigue el patrón de los números impares.
"*" * (level * 2 + 1)
- Abrimos y cerramos los asteriscos con
b_space.b_space + "*" * (level * 2 + 1) + b_space
- Luego, simplemente multiplicamos todo por la cantidad de triángulos apilados uno al lado del otro horizontalmente.
(b_space + "*" * (level * 2 + 1) + b_space) * (triangle * 2 + 1)
Juntando todo, obtenemos la línea, la desmontamos a la derecha y la imprimimos.
line = (a_space + (b_space + "*" * (level * 2 + 1) + b_space) * (triangle * 2 + 1)).rstrip() print(line)Probémoslo con algunos casos de prueba.
n = 1 *n = 2 * *** * * * *********n = 3 * *** ***** * * * *** *** *** *************** * * * * * *** *** *** *** *** *************************n = 4 * *** ***** ******* * * * *** *** *** ***** ***** ***** ********************* * * * * * *** *** *** *** *** ***** ***** ***** ***** ***** *********************************** * * * * * * * *** *** *** *** *** *** *** ***** ***** ***** ***** ***** ***** ***** *************************************************Usando una función auxiliar para construir los sub-triángulos:
def tri(n): r = [(s:=(' '*(((2*n-1)-(2*i-1))//2)))+('*'*(2*i-1))+s for i in range(1, n+1)] return r def triangle(n): v = [''.join(j) for i in range(n+1) for j in zip(*[tri(n) for _ in range(2*i-1)])] return '\n'.join((s:=' '*((len(v[-1]) - len(i))//2))+i+s for i in v) for i in range(1, 4): print(triangle(i)) print('-'*25) * ------------------------- * *** * * * ********* ------------------------- * *** ***** * * * *** *** *** *************** * * * * * *** *** *** *** *** ************************* -------------------------Solo otra alternativa con una función para dibujar el triángulo interior y una función principal para imprimir el resultado final.
import sys n = int(sys.argv[1]) def drawtriangle(num_lines): # prepares the inner triagle in a list and return it together with its width (size). size = (2*num_lines)-1 triangle = [] for i in range(num_lines): white_side = num_lines - i - 1 asterisks = 2*i + 1 triangle.append(" "*white_side + "*"*asterisks + " "*white_side) return triangle, size def main(num_lines): tr, tr_size = drawtriangle(num_lines) for j in range(num_lines): for line in tr: white_triangles = n - j - 1 white_size = tr_size * white_triangles line_repeat = (2*j) + 1 print(" "*white_size + line*line_repeat + " "*white_size) main(n)Producción:
* * *** * * * ********* * *** ***** * * * *** *** *** *************** * * * * * *** *** *** *** *** ************************* * *** ***** ******* * * * *** *** *** ***** ***** ***** ********************* * * * * * *** *** *** *** *** ***** ***** ***** ***** ***** *********************************** * * * * * * * *** *** *** *** *** *** *** ***** ***** ***** ***** ***** ***** ***** *************************************************El programa que creó para imprimir un solo triángulo no es útil en este caso, ya que eso significaría que debe imprimir estos triángulos uno al lado del otro alineados en la salida estándar. Solo se puede imprimir línea por línea, y es bastante simple hacerlo. Aquí hay un enfoque ingenuo que no involucra ninguna matemática seria.
rows = int(input()) p = 2 * rows *(rows - 1) # Variable to print the left most spaces x = " " for i in range(rows): # For every row space = 2 * (rows - 1) # Space variable to print spaces after an asterisk when needed for j in range(rows): # For every row inside the row print(p * x, end="") # print the left most spaces for k in range(2*(i + 1) - 1): print((2*(j + 1) - 1) * "*", end = "") # Print the asterisk(s) based on the row number print(space * x, end = "") # Print spaces(s) after the asterisk(s) space -= 2 # Decrement the number of spaces to be printed after an asterisk for every row p -= 1 # Every row has one lesser space on the left print() # Print a new line after every row p -= (rows - 1) # Update the number of spaces to be printed on the left most side for every outer rowVaya a través de los comentarios de arriba para más detalles. Las salidas:
norte = 4
* *** ***** ******* * * * *** *** *** ***** ***** ***** ********************* * * * * * *** *** *** *** *** ***** ***** ***** ***** ***** *********************************** * * * * * * * *** *** *** *** *** *** *** ***** ***** ***** ***** ***** ***** ***** *************************************************norte = 5
* *** ***** ******* ********* * * * *** *** *** ***** ***** ***** ******* ******* ******* *************************** * * * * * *** *** *** *** *** ***** ***** ***** ***** ***** ******* ******* ******* ******* ******* ********************************************* * * * * * * * *** *** *** *** *** *** *** ***** ***** ***** ***** ***** ***** ***** ******* ******* ******* ******* ******* ******* ******* *************************************************************** * * * * * * * * * *** *** *** *** *** *** *** *** *** ***** ***** ***** ***** ***** ***** ***** ***** ***** ******* ******* ******* ******* ******* ******* ******* ******* ******* *********************************************************************************Y así. Como ya se mencionó, este es un enfoque ingenuo para la intuición.
Esto es lo que creo que este ejercicio está tratando de enseñarte.
Tomemos su código de triángulo (no hay nada fundamentalmente malo en él):
size = int(input()) for i in range(size): for j in range(i, size): print(" ", end = "") for j in range(i): print("*", end = "") for j in range(i + 1): print("*", end = "") print()y convertirlo en una función que devuelve una lista de filas/líneas:
def triangle(size): rows = [] for i in range(size): row = [] for j in range(i + 1, size): row.append(" ") for j in range(2 * i + 1): # i + (i+1) = 2*i+1. row.append("*") for j in range(i + 1, size): # Let's add spaces at the end, too. row.append(" ") # It'll make sense in a moment! rows.append("".join(row)) return rows for row in triangle(5): print(row) # * # *** # ***** # ******* # ********* Ahora podemos modificarlo un poco para que funcione con cualquier "bloque de construcción" de lista de cadenas rectangular en lugar de * :
def triangle(size, block): rows = [] for i in range(size): strip = [[] for _ in block] for j in range(i + 1, size): for s, b in zip(strip, block): s.append(" " * len(b)) # Space as wide as the building block for j in range(2 * i + 1): for s, b in zip(strip, block): s.append(b) for j in range(i + 1, size): for s, b in zip(strip, block): s.append(" " * len(b)) for s in strip: rows.append("".join(s)) return rows # Make a triangle out of ["abc", # "def"]: for row in triangle(3, ["abc", "def"]): print(row) # abc # def # abcabcabc # defdefdef # abcabcabcabcabc # defdefdefdefdef ¡Este es un código algo complicado! Intente agregar algunas declaraciones de print() a este código para ver cómo funciona. zip() recorre dos listas en paralelo. En realidad, debería intentar reescribir esta función usted mismo desde cero.
La recompensa es muy satisfactoria: 🙂
fractal = triangle(4, triangle(4, ["*"])) for row in fractal: print(row) # * # *** # ***** # ******* # * * * # *** *** *** # ***** ***** ***** # ********************* # * * * * * # *** *** *** *** *** # ***** ***** ***** ***** ***** # *********************************** # * * * * * * * # *** *** *** *** *** *** *** # ***** ***** ***** ***** ***** ***** ***** # *************************************************Por supuesto, ahora también puede crear un "triángulo de triángulos de triángulos":
for row in triangle(2, triangle(2, triangle(2, ["()"]))): print(row) # () # ()()() # () () () # ()()()()()()()()() # () () () # ()()() ()()() ()()() # () () () () () () () () () # ()()()()()()()()()()()()()()()()()()()()()()()()()()()La lección aquí es la de generalizar un problema: a primera vista, es difícil hacer un triángulo de triángulos (de triángulos). Pero es relativamente fácil hacer un triángulo con lo que sea .
Si escribimos algún código que pueda hacer triángulos a partir de cualquier cosa (como nuestro ejemplo de abc def ), podemos usar ese código para hacer un triángulo a partir de triángulos.
A diferencia de las otras respuestas, no necesitamos una lógica separada para las dos capas de "triángulo" en juego aquí.
Ya hay muchas respuestas interesantes, pero pensé en agregar una que permita a Python manejar el centrado de cadenas.
def print_fractal(n, char='*'): # Width of single triangle base = 2*n - 1 # Width of overall figure width = base**2 # Lines containing single triangle padded to rectangle of width `base` lines = [f'{(2*line + 1)*char:^{base}}' for line in range(n)] for row in range(n): # Print (2*row + 1) triangle blocks next to each other for line in lines: print(f'{(2*row + 1)*line:^{width}}') >>> print_fractal(3) * *** ***** * * * *** *** *** *************** * * * * * *** *** *** *** *** *************************También se sugiere una solución recursiva, gracias a la inspiración de la respuesta de @Lynn :
def make_fractal(n, depth, block=['*']): if not depth: return block width = (2*n - 1)*max(map(len, block)) lines = [] for row in range(n): for line in block: lines.append(f'{(2*row + 1)*line:^{width}}') return make_fractal(n, depth - 1, lines) >>> for line in make_fractal(3, 2): print(line) * *** ***** * * * *** *** *** *************** * * * * * *** *** *** *** *** ************************* >>> for line in make_fractal(2, 3): print(line) * *** * * * ********* * * * *** *** *** * * * * * * * * * *************************** >>> for line in make_fractal(2, 2, [' . ', '---']): print(line) . --- . . . --------- . . . --- --- --- . . . . . . . . . ---------------------------