patternpythonMinor
Solution for puzzle 3d x 1d = 2d x 2d in Python
Viewed 0 times
pythonsolutionpuzzlefor
Problem
I wanted to resolve the puzzle from this link using Python 3. It works and gives me the correct value but I would like to know if it is possible to resolve this problem with a few lines or how I can improve/optimize my code.
And this is the result:
import time
start = time.time()
max=0
gx=0
gy=0
gi=0
gj=0
for i in range(999,99,-1):
for j in range(9,0,-1):
mul=i*j
for x in range(99,9,-1):
for y in range(99,9,-1):
mul2=x*y
if mul==mul2:
if mul>max:
gx=x
gy=y
gi=i
gj=j
max=mul
print ("i: " + str(gi))
print ("j: " + str(gj))
print ("x: " + str(gx))
print ("y: " + str(gy))
print ("max: " + str(max))
end = time.time()
print (end - start)And this is the result:
i: 992
j: 9
x: 96
y: 93
max: 8928
17.678768157958984Solution
Style
Python has a style guide called PEP8. It is definitly worth a read. Among the few things you could do to make your code more pythonic : spacing around operators. Also, you should try to avoid giving your variables the same name as builtins. Furthermore, you can assign all variables in one go if it corresponds to a single logical operation (as in "saving the best result found so far"). Finally, you can remove explicit conversion when printing :
Algorithm
For each
This makes your code go roughly 500 times faster.
From this point, it is hard to make things actually faster but let's try.
Once you have
Once you have it, you can break because it will only find the same solution.
Similarly, you can break out of the
Also, in the
This seems to be roughly 10 000 times faster than it used to be.
Python has a style guide called PEP8. It is definitly worth a read. Among the few things you could do to make your code more pythonic : spacing around operators. Also, you should try to avoid giving your variables the same name as builtins. Furthermore, you can assign all variables in one go if it corresponds to a single logical operation (as in "saving the best result found so far"). Finally, you can remove explicit conversion when printing :
import time
start = time.time()
maxi, gx, gy, gi, gj = 0, 0, 0, 0, 0
for i in range(999, 99, -1):
for j in range(9, 0, -1):
mul = i * j
for x in range(99, 9, -1):
for y in range(99, 9, -1):
mul2 = x*y
if mul == mul2:
if mul > maxi:
maxi, gx, gy, gi, gj = mul, x, y, i, j
print("i: ", gi)
print("j: ", gj)
print("x: ", gx)
print("y: ", gy)
print("max: ", maxi)
end = time.time()
print(end - startAlgorithm
For each
i, j, it only makes sense to check if it can be written under the form _ _ * _ _ if it is bigger than the current best value.for i in range(999, 99, -1):
for j in range(9, 0, -1):
mul = i * j
if mul > maxi:
for x in range(99, 9, -1):
for y in range(99, 9, -1):
mul2 = x*y
if mul == mul2:
maxi, gx, gy, gi, gj = mul, x, y, i, jThis makes your code go roughly 500 times faster.
From this point, it is hard to make things actually faster but let's try.
Once you have
mul, to find 2 divisors under of 2 digits, you don't need have two loops : one is enough and then you check if the number actually divides mul and if the result has 2 digits.if mul > maxi:
for x in range(99, 9, -1):
y, r = divmod(mul, x)
if r == 0 and 10 <= y < 100:
axi, gx, gy, gi, gj = mul, x, y, i, jOnce you have it, you can break because it will only find the same solution.
if mul > maxi:
for x in range(99, 9, -1):
y, r = divmod(mul, x)
if r == 0 and 10 <= y < 100:
maxi, gx, gy, gi, gj = mul, x, y, i, j
breakSimilarly, you can break out of the
j loop when mul <= maxi because mul goes decreasing.for i in range(999, 99, -1):
for j in range(9, 0, -1):
mul = i * j
if mul <= maxi:
break
else:
for x in range(99, 9, -1):
y, r = divmod(mul, x)
if r == 0 and 10 <= y < 100:
maxi, gx, gy, gi, gj = mul, x, y, i, j
breakAlso, in the
x loop, it doesn't make sense anymore to do backward.for i in range(999, 99, -1):
for j in range(9, 0, -1):
mul = i * j
if mul <= maxi:
break
else:
for x in range(10, 100):
y, r = divmod(mul, x)
if r == 0 and 10 <= y < 100:
maxi, gx, gy, gi, gj = mul, x, y, i, j
print(maxi)
breakThis seems to be roughly 10 000 times faster than it used to be.
Code Snippets
import time
start = time.time()
maxi, gx, gy, gi, gj = 0, 0, 0, 0, 0
for i in range(999, 99, -1):
for j in range(9, 0, -1):
mul = i * j
for x in range(99, 9, -1):
for y in range(99, 9, -1):
mul2 = x*y
if mul == mul2:
if mul > maxi:
maxi, gx, gy, gi, gj = mul, x, y, i, j
print("i: ", gi)
print("j: ", gj)
print("x: ", gx)
print("y: ", gy)
print("max: ", maxi)
end = time.time()
print(end - startfor i in range(999, 99, -1):
for j in range(9, 0, -1):
mul = i * j
if mul > maxi:
for x in range(99, 9, -1):
for y in range(99, 9, -1):
mul2 = x*y
if mul == mul2:
maxi, gx, gy, gi, gj = mul, x, y, i, jif mul > maxi:
for x in range(99, 9, -1):
y, r = divmod(mul, x)
if r == 0 and 10 <= y < 100:
axi, gx, gy, gi, gj = mul, x, y, i, jif mul > maxi:
for x in range(99, 9, -1):
y, r = divmod(mul, x)
if r == 0 and 10 <= y < 100:
maxi, gx, gy, gi, gj = mul, x, y, i, j
breakfor i in range(999, 99, -1):
for j in range(9, 0, -1):
mul = i * j
if mul <= maxi:
break
else:
for x in range(99, 9, -1):
y, r = divmod(mul, x)
if r == 0 and 10 <= y < 100:
maxi, gx, gy, gi, gj = mul, x, y, i, j
breakContext
StackExchange Code Review Q#79092, answer score: 4
Revisions (0)
No revisions yet.