Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Brute Force Works

Last ni­gh­t, Juan­jo Conti twee­ted this:

Or, in en­glis­h: "U­sing exac­tly on­ce the di­gi­ts 1,3,4 and 6, and any of the four ba­sic ope­ra­tion­s, ob­tain 24."

I first spent a cou­ple of mi­nu­tes thi­nking about it and then it hit me: the­re is no point in thi­nking this sort of pro­ble­m, be­cau­se:

  1. Bru­­te fo­r­­cing it wi­­ll take le­ss ti­­me

  2. What you do whi­­le "thi­nki­n­­g" it is sort of la­­me, is­n't it?

So, he­re is a mo­re-o­r-­le­ss ge­ne­ral so­lu­tion for any of the­se pro­ble­ms.

from __future__ import print_function, division
import itertools

numbers = ['1','3','4','6']
target = 24

# Having '' as an operation allows for solution (14-6)*3, which
# may or may not be valid depending on rule interpretation.
operations =  ['*','/','+','-','']

t1='(({0}{4}{1}){5}{2}){6}{3}'
t2='{0}{4}({1}{5}({2}{6}{3}))'

for nums in itertools.permutations(numbers):
    for ops1 in itertools.combinations_with_replacement(operations, 3):
        for ops2 in itertools.permutations(ops1):
            for t in (t1, t2):
                s = t.format(*(nums+ops2))
                #print(repr(s))
                try:
                    if eval(s) == target:
                        print(s)
                except (ZeroDivisionError, SyntaxError, TypeError):
                    continue

Of course you can make it solve any problem of this class by adjusting numbers and target. There is also a possible extra solution if eval(s) == -tar­get where you just need to add a unary - to the expression, but who cares.

Did I miss so­me­thin­g? Is this rea­lly a ge­ne­ral so­lu­tio­n?


Contents © 2000-2024 Roberto Alsina