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()
I have simplified the following code so it should now look more clear easy to understand than it used to be.
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)
This approach prints out everything in one pass. In the following explanation, I will break down the components of the code, what these variables mean, and how they work.
The first variable that I should mention is n
, the number of levels, or the height of every triangle. It is also the number of triangles stacked on top of each other.
The second variable is rows
, the number of rows in the output. We can see a pattern that the number of rows is equal to n
squared.
The next variable is base
. It is the number of asterisks at the bottom level of the triangle. It also follows a pattern of odd numbers as we may have noticed.
After that, our loop begins, iterates through every row, and prints out the result.
These variables tell us which triangle and level of the triangle we are currently at. You can try it yourself by printing out triangle
and level
every iteration.
for row in range(rows):
triangle = row // n
level = row % n
print(triangle, level)
The next part is the indentation. Just to give you a brief idea of what a_space
and b_space
are, here is a visual representation that describes the spaces.
a_space
shrinks after every triangle, and b_space
shrinks after every level.
a_space = " " * (n - triangle - 1) * base
b_space = " " * (n - level - 1)
We multiply a_space
by base
because one a_space
has a length equal to the base.
Let's look at it step-by-step.
- First, we start our line with
a_space
.a_space
- Then, we print out the asterisks. The number of asterisks follows the pattern of odd numbers.
"*" * (level * 2 + 1)
- We open and close the asterisks with
b_space
.b_space + "*" * (level * 2 + 1) + b_space
- Then, we simply multiply the whole thing by the number of triangles stacked next to each other horizontally.
(b_space + "*" * (level * 2 + 1) + b_space) * (triangle * 2 + 1)
Putting everything together, we get the line, right-strip it, and print it out.
line = (a_space + (b_space + "*" * (level * 2 + 1) + b_space)
* (triangle * 2 + 1)).rstrip()
print(line)
Let's try it out with a few test cases.
n = 1
*
n = 2
*
***
* * *
*********
n = 3
*
***
*****
* * *
*** *** ***
***************
* * * * *
*** *** *** *** ***
*************************
n = 4
*
***
*****
*******
* * *
*** *** ***
***** ***** *****
*********************
* * * * *
*** *** *** *** ***
***** ***** ***** ***** *****
***********************************
* * * * * * *
*** *** *** *** *** *** ***
***** ***** ***** ***** ***** ***** *****
*************************************************
Here is what I think this exercise is trying to teach you.
Let's take your triangle code (there is nothing fundamentally wrong with it):
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()
and turn it into a function that returns a list of rows/lines:
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)
# *
# ***
# *****
# *******
# *********
Now we can tweak it a little bit to work with any rectangular list-of-strings "building block" instead of *
:
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
This is somewhat tricky code! Try adding some print()
statements to this code to see how it works. zip()
loops over two lists in parallel. Actually, you should try rewriting this function yourself from scratch.
The payoff is very satisfying: 🙂
fractal = triangle(4, triangle(4, ["*"]))
for row in fractal:
print(row)
# *
# ***
# *****
# *******
# * * *
# *** *** ***
# ***** ***** *****
# *********************
# * * * * *
# *** *** *** *** ***
# ***** ***** ***** ***** *****
# ***********************************
# * * * * * * *
# *** *** *** *** *** *** ***
# ***** ***** ***** ***** ***** ***** *****
# *************************************************
You can of course also now create a "triangle of triangles of triangles":
for row in triangle(2, triangle(2, triangle(2, ["()"]))):
print(row)
# ()
# ()()()
# () () ()
# ()()()()()()()()()
# () () ()
# ()()() ()()() ()()()
# () () () () () () () () ()
# ()()()()()()()()()()()()()()()()()()()()()()()()()()()
The lesson here is that of generalizing a problem: on the face of it, it's hard to make a triangle of triangles (of triangles). But it's relatively easy to make a triangle out of whatever.
If we write some code that can make triangles out of anything (like our abc def
example), we can use that code to make a triangle out of triangles.
Unlike the other answers, we don't need separate logic for the two layers of "triangle" at play here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With