2
\$\begingroup\$

I used Python to write the following program:

"""
A desired equation includes a 4-digit integer multiplied with a single-digit integer
to give another 4-digit integer and all 9 digits(1-9) are used in the equation.
"""

import random

found=False

while not found:
    full_range=range(1,10)

    four_digit_num=""
    multiple=""
    for i in range(4):
        four_digit_num+=str(full_range.pop(random.randint(1,len(full_range)-1)))

    single_digit_num=full_range.pop(random.randint(1,len(full_range)-1))

    for i in range(4):
        multiple+=str(full_range.pop(random.randint(1,len(full_range)-1)))

    if int(four_digit_num)*single_digit_num==int(multiple):
        found=True

#output the equation
print "The desired equation is:"
print four_digit_num+"*"+str(single_digit_num)+"="+multiple

Is there any better way to perform this task?

\$\endgroup\$
  • \$\begingroup\$ Without getting into the math (because I don't do math). four_digit_num="" multiple="" refactors to four_digit_num=multiple="" \$\endgroup\$ – Scüter Jun 27 '14 at 2:35
2
\$\begingroup\$

It is extremely inefficient to do this randomly; you could end up checking the same numbers again and again. For a more structured approach, you could use itertools.permutations:

from itertools import permutations

for nums in permutations("123456789"):
    a = int("".join(nums[:4]))
    b = int(nums[4])
    c = int("".join(nums[5:]))
    if a * b == c:
        print "{0} * {1} == {2}".format(a, b, c)
        break # optional - there's more than one answer!

Also, note that:

found=False
while not found:
    ...
    if int(four_digit_num)*single_digit_num==int(multiple):
        found=True

would be neater as:

while True:
    ...
    if int(four_digit_num) * single_digit_num == int(multiple):
        break
\$\endgroup\$
1
\$\begingroup\$

What about simple brute force?

def check(i, j, c):
    istr = list(str(i))
    cstr = list(str(c))
    if "0" in istr: istr.remove("0")
    if "0" in cstr: cstr.remove("0")
    Jval = ["%d"%j]
    Set_String = set(istr + cstr + Jval)
    return len(Set_String) == 9

for i in range(1000, 10000):
    for j in range(2, 10):
        c = i * j
        if c < 10000 and check(i, j, c): 
                print "The desired equation is: %d * %d = %d" %(min(i,c), j , max(i,c))i/j, max(i,j))
\$\endgroup\$
  • \$\begingroup\$ Can't you just make i go in [1000, 10000[ and j go in [2, 10[ and then consider i, j, i*j ? You should shave off useless checks by considering when the product i*j becomes bigger than 9999. \$\endgroup\$ – Josay Jun 24 '14 at 7:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.