# Printing reverse number triangle

I have to write a program in python that will take a number and print a right triangle attempting to use all numbers from 1 to that number. For example:

Enter number: 10
Output:
7 8 9 10
4 5 6
2 3
1

Enter number: 6
Output:
4 5 6
2 3
1

Enter number: 20
Output:
11 12 13 14 15
7 8 9 10
4 5 6
2 3
1


For which I have written the following function

def print_right_triangle(num):
c = 1
k = 0
l = []
while(k < num-1):
v = []
for i in range(c):
v.append(k+1)
k += 1
c += 1
if k > num:
break
l.append(v)

p = len(l)
for i in range(p):
for j in l[p-(i+1)]:
print(j, end=' ')
print()
return None

print_right_triangle(10)


It's giving the same output and solved my problem. I was wondering is there any more pythonic way to do this

• One liner with a bit of maths to find x(x+1)/2 = n: lambda x: [print(*range(1+i*~-i//2, 1+i*-~i//2)) for i in range(int(((1+8*x)**.5-1)/2), 0, -1)] Commented Nov 19, 2021 at 11:43
• @rak1507 Thank you so much!!! Commented Nov 19, 2021 at 13:27
• @rak1507 could you please explain 1+i*~-i//2 this, its so tricky to understand this Commented Nov 19, 2021 at 14:14
• ~-i is magic for (i-1) so it's 1 + i * (i-1) // 2 (sorry: code golfing habits die hard) Commented Nov 19, 2021 at 14:38
• @rak1507 ohhokay....got it..thank you so much for responding! Commented Nov 19, 2021 at 18:54

### Optimized != pythonic

Optimized means "spending less resources". "Pythonic" means "using idiomatic Python features". Sometimes they come together, sometimes don't. Pythonic code is clean and maintainable, while optimized can be very unclear and need many comments.

### Make more use of Python features

List comprehensions, range arguments and unpacking can be very handy. This code

    v = []
for i in range(c):
v.append(k+1)
k += 1


is clearly just a

    v = [k+1+i for i in range(c)]
k += c


and, changing the range arguments,

    v = list(range(k+1, k+c))
k += c


And this code

    for j in l[p-(i+1)]:
print(j, end=' ')
print()


can be written as

    print(*l[p-(i+1)])


and

p = len(l)
for i in range(p):
print(*l[p-(i+1)])


is walking the l list backwards, so it's

for line in reversed(l):
print(*line)


This is pythonic.

### Optimizations

Change the algorithm. Here you're gathering all the number in a list to output them. But the numbers are all in order, so you can easily avoid lists at all - just make loops with prints.

Now you know that only numbers that equal n*(n+1)/2 can be used to build such triangles. You can solve n*(n+1)/2 = num as a quadratic equation and round n down to get the number of lines without loops like rak1507 did.