Reputation: 162
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!
Upvotes: 2
Views: 19937
Reputation: 54313
We assume that x,y,z
must be positive integers. There's an infinity of solutions otherwise.
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.
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))
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 :)
Upvotes: 13
Reputation: 897
This will make you a generator of list containing your x,y,z values that produce 1950. The advantage of the generator construct is that the values are generated when called for instead of then the object is created.
the_vals = ([x,y,z] for x in range(500) for y in range(500) for z in range(500) if (x * 80) + (z * 65) + (y * 50) == 1950)
Then to print it out you can just do
for x,y,z in the_vals:
print("x " + str(x) + " z " + str(z) + " y " + str(y))
Upvotes: 3