1
\$\begingroup\$

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

200_success
146k22 gold badges190 silver badges479 bronze badges
asked Nov 19, 2021 at 11:13
\$\endgroup\$
5
  • 2
    \$\begingroup\$ 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)] \$\endgroup\$ Commented Nov 19, 2021 at 11:43
  • \$\begingroup\$ @rak1507 Thank you so much!!! \$\endgroup\$ Commented Nov 19, 2021 at 13:27
  • \$\begingroup\$ @rak1507 could you please explain 1+i*~-i//2 this, its so tricky to understand this \$\endgroup\$ Commented Nov 19, 2021 at 14:14
  • 1
    \$\begingroup\$ ~-i is magic for (i-1) so it's 1 + i * (i-1) // 2 (sorry: code golfing habits die hard) \$\endgroup\$ Commented Nov 19, 2021 at 14:38
  • \$\begingroup\$ @rak1507 ohhokay....got it..thank you so much for responding! \$\endgroup\$ Commented Nov 19, 2021 at 18:54

1 Answer 1

3
\$\begingroup\$

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.

Anyway, optimization should start with making the code readable, and pythonic code should be readable.

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.

First, read some theory.

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.

Next, find formulas for starting and ending numbers in each line to put them into range arguments.

And now you can code it in three lines.

answered Nov 19, 2021 at 12:38
\$\endgroup\$
1
  • \$\begingroup\$ Thank you so much!! for this wonderful explaination \$\endgroup\$ Commented Nov 19, 2021 at 13:27

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.