In [1]:
from gmpy2 import mpq # not used, the formula is evaluted the python way, not mathematically
from __future__ import division
from itertools import *
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
# originally, use the code from http://mattdodge.net/24-a-childhood-game-taken-to-the-next-level/
# but it is buggy, cannot find solution of [12,12,12,10]
# so I wrote my own
def ev(nums):
if len(nums)==1:
return {nums[0]:"%d"%nums[0], -nums[0]:"-%d"%nums[0]}
rtn =dict()
for idx in powerset(range(len(nums))):
if len(idx) in (0, len(nums)):
continue
s1 = sorted(nums[i] for i in idx)
s2 = sorted(nums[i] for i in range(len(nums)) if i not in idx)
if s1>s2:
continue
r1, r2 = ev(s1), ev(s2)
for a,a1 in r1.items():
for b,b1 in r2.items():
rtn[a+b]="(%s)+(%s)"%(a1,b1)
rtn[a*b]="(%s)*(%s)"%(a1,b1)
# the code is ugly because it was originally wrote for rational numbers (mpq)
# but then, modified the code for floating numbers instead because of // operator
try:
rtn[a/b]="(%s)/(%s)"%(a1,b1)
except:
pass
try:
rtn[b/a]="(%s)/(%s)"%(b1,a1)
except:
pass
try:
rtn[a//b]="(%s)//(%s)"%(a1,b1)
except:
pass
try:
rtn[b//a]="(%s)//(%s)"%(b1,a1)
except:
pass
rtn[a-b]="(%s)-(%s)"%(a1,b1)
rtn[b-a]="(%s)-(%s)"%(b1,a1)
try:
if b< 100: # avoid very large power
rtn[a**b]="(%s)**(%s)"%(a1,b1)
except:
pass
try:
if a< 100:
rtn[b**a]="(%s)**(%s)"%(b1,a1)
except:
pass
return rtn

def solve(n, nums):
n = float(n)
rtn = ev(nums)
for k,v in rtn.items():
if abs(k-n)<0.000000001:
return v


In [2]:
solve(24, [5,5,5,2])

Out[2]:
'(-5)//(((-2)//(5))/(5))'
In [3]:
import telnetlib
import sys
tel = telnetlib.Telnet("210.65.89.59",2424)
print "start"
sys.stdout.flush()
for i in range(1,25):
r = tel.read_until("Question (%d of 24): "%i)
print r
sys.stdout.flush()
nums = map(int, r[1:-1].split(","))
ans = solve(24, nums)
print nums, ans
sys.stdout.flush()
tel.write("%s\n"%ans)

start
===================================================
===           Welcome to the 24 game!           ===
=== You have 2 minutes to answer all questions. ===
===================================================

Question (1 of 24):
[12, 1, 1, 1] (-12)//(((-1)+(-1))**(-1))

Question (2 of 24):
[4, 2, 6, 6] ((6)//((-2)//(6)))*(-4)

Question (3 of 24):
[8, 12, 5, 5] (((5)*(5))//(-12))*(-8)

Question (4 of 24):
[8, 8, 6, 5] (8)-(((-6)//(5))*(8))

Question (5 of 24):
[5, 2, 4, 2] (((2)//(-2))-(5))*(-4)

Question (6 of 24):
[9, 3, 5, 4] (((-3)//(9))-(5))*(-4)

Question (7 of 24):
[5, 7, 2, 11] (-5)-((-7)-((-2)*(-11)))

Question (8 of 24):
[7, 11, 1, 4] (-11)-(((-1)-(4))*(7))

Question (9 of 24):
[10, 10, 9, 2] (10)-(((10)//(-2))+(-9))

Question (10 of 24):
[7, 2, 7, 10] (((10)/(7))-(-2))*(7)

Question (11 of 24):
[3, 7, 3, 7] ((-3)-((-3)/(-7)))*(-7)

Question (12 of 24):
[1, 4, 5, 6] (((-1)//(6))-(5))*(-4)

Question (13 of 24):
[10, 10, 4, 2] ((-2)+((4)/(-10)))*(-10)

Question (14 of 24):
[5, 10, 5, 2] (((-2)/(10))+(5))*(5)

Question (15 of 24):
[7, 5, 7, 11] (7)//(((11)//(5))/(7))

Question (16 of 24):
[11, 2, 1, 5] (11)//((5)**((-2)**(-1)))

Question (17 of 24):
[8, 2, 1, 12] (((-1)//(12))+(-2))*(-8)

Question (18 of 24):
[3, 5, 5, 5] (-5)//(((-3)//(5))/(5))

Question (19 of 24):
[5, 1, 11, 13] (11)-((13)//((-1)**(5)))

Question (20 of 24):
[5, 5, 5, 13] ((5)*(5))+((5)//(-13))

Question (21 of 24):
[12, 13, 7, 13] (12)-((-13)-((7)//(-13)))

Question (22 of 24):
[10, 10, 12, 6] (10)-(((-10)//(6))-(12))