Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - faster way to do for loops

I was just wondering if anyone knew a faster / more efficient way to test this.

(It's suppose to write out every solution to the equation)

        for z in range(500):
           for x in range(500):
             for y in range(500):
               if (x * 80) + (z * 65) + (y * 50) == 1950:
                 print("x " + str(x) + " z " + str(z) + " y " + str(y))

Thanks!

like image 211
Aplex Avatar asked Nov 22 '25 09:11

Aplex


1 Answers

We assume that x,y,z must be positive integers. There's an infinity of solutions otherwise.

Calculate y from x and z

Here's a method which should be 500x faster than yours, simply because it doesn't iterate over y :

for z in range(500):
    for x in range(500):
        fifty_y = 1950 - (x * 80) - (z * 65)
        if fifty_y >= 0 and (fifty_y % 50) == 0:
            y = fifty_y // 50
            print("x " + str(x) + " z " + str(z) + " y " + str(y))

By iterating over x, y and z, you're basically shooting in the dark and hoping that it lands on 1950.

But you know that 50 * y = 1950 - x * 80 - z * 65, so you can calculate y directly from x and z.

50 * y should be positive, and if y is to be an integer, it should be divisible by 50.

Restrict x and z

range(500) is far too big for x and z if we want y to be positive.

range(1950 // 65 + 1) should be enough for z.

Knowing z, range((1950 - 65 * z)// 80 + 1) will be enough for x.

As a bonus, we're sure that 50 * y is positive and we can remove one test :

for z in range(1950 // 65 + 1):
    for x in range((1950 - 65 * z) // 80 + 1):
        fifty_y = 1950 - (x * 80) - (z * 65)
        if (fifty_y % 50) == 0:
            y = fifty_y // 50
            print("x " + str(x) + " z " + str(z) + " y " + str(y))

With Wolfram Alpha

By typing the equation in wolfram alpha, we get :

Integer solution: y = 13 n + x, z = -10 n - 2 x + 30, n element Z

That's perfect! For any x, we just need to choose n so that both y and z are positive. There's no need for if anymore. This code iterates 42 times to display 42 solutions :

for x in range(1950 // 80 + 1):
    for n in range(- (x // 13), (30 - 2 * x) // 10 + 1):
        z = -10 * n - 2 * x + 30
        y = 13 * n + x
        print("x " + str(x) + " z " + str(z) + " y " + str(y))

It almost fits in one line :

print [(x, 13 * n + x, 30 - 10 * n - 2 * x) for x in range(25) for n in range(-(x // 13), (30 - 2 * x) // 10 + 1)]

This code is alsost 3 million times faster than your original code :)

like image 93
Eric Duminil Avatar answered Nov 24 '25 00:11

Eric Duminil