Reputation: 21
Write a recursive function called draw_triangle() that outputs lines of *'s to form a right side up isosceles triangle. Function draw_triangle() has one parameter, an integer representing the base length of the triangle. Assume the base length is always odd and less than 20. Output 9 spaces before the first '*' on the first line for correct formatting.
Hint: The number of '*' increases by 2 for every line drawn.
Ex: If the input of the program is: 3
,
Then the function draw_triangle outputs:
*
***
If the input of the program is 19
,
Then the function outputs
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
No space is output before the first asterisk on the last line when the base length is 19.
I was able to code this non-recursively as follows:
def draw_triangle(n):
lines_to_print = int(((n // 2) + 1))
spaces_to_print = 9
asts_to_print = 1
for i in range(lines_to_print):
print(spaces_to_print * ' ', end='')
print(asts_to_print * '*', end='')
print()
spaces_to_print -= 1
asts_to_print += 2
base_length = int(input())
draw_triangle(base_length)
But I cannot, for my life, figure out how to do it recursively, let alone with only one argument. What am I missing about recursion?
Upvotes: 2
Views: 6955
Reputation: 85
Based on others' answers, here is a recursive solution that has only length
as its parameter:
base_length = 0
def draw_triangle(length: int):
global base_length
if base_length == 0:
base_length = length
if length > 1:
draw_triangle(length - 2)
print(('*' * length).center(base_length))
if base_length == length:
base_length = 0
Upvotes: 0
Reputation: 5559
The simple trick here is to use the str.center() method.
def draw_triangle(n):
if n == 1:
print('*'.center(19))
else:
draw_triangle(n-2)
print((n*'*').center(19))
Test it:
draw_triangle(19)
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
Upvotes: 1
Reputation: 357
Well, it is a quite interesting question. The main obstacle is that you have to preserve initial base length of triangle. You can't save it via assigning input value to another parameter inside a recursive function because:
Not sure if the following code is convenient with the conditions of the task but it may be useful to illustrate an idea of recursive functions for you:
base_length = 20
def draw_triangle(base=base_length):
if base % 2 == 0:
base = base - 1
draw_triangle(base)
else:
if base > 0:
# print(base)
# print(int(base/2 - 1))
print(' '*int((base - 2)/2+1) + '*'*(base_length - base) + ' '*int((base - 2)/2))
base = base - 2
draw_triangle(base)
elif base == 0:
return 0
draw_triangle(base=base_length)
Formally there is only one argument in this recursive function, but you have to define base_length
paramater outside of the function and the function uses base_length
inside.
Upvotes: 0
Reputation: 1584
By printing after the recursion itself happens, you can print smaller lines over the bigger lines:
def draw_triangle(n):
spaces = 9 - n // 2 # Ensures correct spacing for each line
if n == 1:
print(spaces * ' ' + '*')
else:
draw_triangle(n-2)
print(spaces * ' ' + n * '*')
draw_triangle(19)
Upvotes: 1
Reputation: 11512
One method is is to define functions to print the symbole you want to use and the spaces between them:
def print_ecart(ecart):
if (ecart == 0):
return;
print(" ", end = "")
print_ecart(ecart - 1)
def print_etoile(etoile):
if(etoile == 0):
return
print("* ", end = "")
print_etoile(etoile - 1)
def pattern(n, num):
if (n == 0):
return
print_ecart(n - 1)
print_etoile(num - n + 1)
print("");
pattern(n - 1, num)
In this case print_ecrat
prints spaces and print_etoile
prints the stars:
pattern(10,10)
returns:
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
* * * * * * * * * *
Upvotes: 0