I need to make a triangle of triangle pattern of * depending on the integer input.
For example:
n = 2 *
***
* * *
*********
n = 3 *
***
*****
* * *
*** *** ***
***************
* * * * *
*** *** *** *** ***
*************************
I've already figured out the code for a single triangle, but I don't know how to duplicate them so they'll appear like a triangle of triangles.
Here's my code for one triangle:
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()
Using a helper function to build the sub-triangles:
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)
*
-------------------------
*
***
* * *
*********
-------------------------
*
***
*****
* * *
*** *** ***
***************
* * * * *
*** *** *** *** ***
*************************
-------------------------
Just another alternative with a function to draw the inner triangle and a main function to print the final result
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)
Output:
*
*
***
* * *
*********
*
***
*****
* * *
*** *** ***
***************
* * * * *
*** *** *** *** ***
*************************
*
***
*****
*******
* * *
*** *** ***
***** ***** *****
*********************
* * * * *
*** *** *** *** ***
***** ***** ***** ***** *****
***********************************
* * * * * * *
*** *** *** *** *** *** ***
***** ***** ***** ***** ***** ***** *****
*************************************************
Lots of interesting answers already, but I thought I'd add one that lets Python handle the string centering.
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)
*
***
*****
* * *
*** *** ***
***************
* * * * *
*** *** *** *** ***
*************************
A recursive solution also suggests itself, thanks to inspiration from @Lynn's answer:
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)
.
---
. . .
---------
. . .
--- --- ---
. . . . . . . . .
---------------------------