Je pense que j'ai joué pour faire 10 en regardant le numéro de la voiture venant en sens inverse, comme lorsque je suis dans une voiture, et en ajoutant, en soustrayant, en multipliant et en divisant. Vous devez faire quelque chose avant de continuer. Aussi, je me demande combien de combinaisons je ne peux pas résoudre. Alors, essayons les quatre paires de nombres 0-9 et combinaisons d'opérateurs et écrivons un programme pour afficher les résultats.
Les références:
Le troisième site de référence est en Python. Cependant, comme la formule est convertie en chaîne de caractères et transmise à la fonction eval, la vitesse d'exécution devient extrêmement lente (FAQ de programmation - documentation Python 2.7ja1:. Voir programmation.html # id20)). Par conséquent, comme le montre le deuxième site de référence, les opérateurs sont six opérateurs avec une distinction dans l'ordre de soustraction et de division. C'est,
from operator import add, sub, mul, div
def rsub(a, b):
return sub(b, a)
def rdiv(a, b):
return div(b, a)
o = [add, sub, rsub, mul, div, rdiv]
Créez une liste d'opérateurs sous forme de. L'opérateur est utilisé trois fois, en supposant que a, b, c, d sont des nombres et o1, o2, o3 sont des opérateurs.
((a o1 b) o2 c) o3 d ・ ・ ・ 1 (a o1 b) o3 (c o2 d) ・ ・ ・ 2
Il n'y a que deux façons.
Il y a 4! = 24 façons de sélectionner a, b, c, d, mais quand 1, il y a des doublons avec a et b remplacés, donc il y a 24/2 = 12 façons de choisir. Plus précisément, si vous écrivez comme suit, la liste «X» listera tous les cas de la chaîne de caractères «q» (comme «1337») sauf les nombres en double (comme «3» dans «1337»). Peut être stocké au format.
from itertools import combinations
q = [float(i) for i in list(q)]
X = []
for a, b in combinations([0, 1, 2, 3], 2):
t = [0, 1, 2, 3]
t.remove(a)
t.remove(b)
x = (q[a], q[b], q[t[0]], q[t[1]])
if not x in X:
X.append(x)
x = (q[a], q[b], q[t[1]], q[t[0]])
if not x in X:
X.append(x)
Dans le cas de 2, il n'est pas nécessaire de penser à la combinaison de a, b, à la combinaison de c, d et à la combinaison de (a, b) et (c, d), donc si vous pensez à la séquence de trois nombres. Je sais que c'est bon. Puisque le nombre est petit, il peut être plus facile à comprendre si vous écrivez solidement plutôt que de penser à des combinaisons.
X = [
(q[0], q[1], q[2], q[3]),
(q[0], q[2], q[1], q[3]),
(q[0], q[3], q[1], q[2]),
]
Quant à la façon de sélectionner o1, 6 choses sont attribuées à 3 places, donc 6 3 = 216 façons doivent être considérées.
from itertools import product
O = [i for i in product(range(6), repeat=3)]
Vous pouvez donc faire toutes les combinaisons.
Après cela, pour toutes les combinaisons de O, nous pouvons calculer les deux modèles en utilisant le contenu de X et enregistrer celui qui devient 10. À ce moment-là, ZeroDivisionError sera affiché, vous devez donc gérer l'exception. J'ai converti la réponse en une chaîne pour la rendre plus facile à voir. De plus, en raison de la nature de l'ordinateur, certaines erreurs peuvent survenir, nous avons donc décidé d'autoriser une erreur d'un nombre (0,001) plus petit que le nombre obtenu en divisant 1 par 9 à la 3e puissance (= 0,0013717421124828531 ...).
Celui qui est réellement fabriqué est illustré ci-dessous. Puisqu'il fonctionnait sur le notebook IPython, il ne s'agit que d'une définition de fonction.
from itertools import permutations, combinations, product
from operator import add, sub, mul, div
from ipython_doctester import test
#@test
def make10(q='1337', verbose=True):
"""Make 10 from 4 numbers(0~9).
q : String, ex) 1337
verbose: Bool, print the results or not
doctest code:
>>> make10()
((7/3)+1)*3
True
"""
q = [float(i) for i in list(q)]
def rsub(a, b):
return sub(b, a)
def rdiv(a, b):
return div(b, a)
o = [add, sub, rsub, mul, div, rdiv]
o_k = ['+', '-', '-', '*', '/', '/']
O = [i for i in product(range(6), repeat=3)]
TOL = 0.001
res = []
for o1, o2, o3 in O:
# ((a o1 b) o2 c) o3 d
X = []
for a, b in combinations([0, 1, 2, 3], 2):
t = [0, 1, 2, 3]
t.remove(a)
t.remove(b)
x = (q[a], q[b], q[t[0]], q[t[1]])
if not x in X:
X.append(x)
x = (q[a], q[b], q[t[1]], q[t[0]])
if not x in X:
X.append(x)
for a, b, c, d in X:
try:
result = o[o3](o[o2](o[o1](a,b),c),d)
except ZeroDivisionError:
continue
if abs(result - 10) < TOL:
if o1 == 2 or o1 == 5:
a, b = b, a
p1 = "(%d%s%d)" % (a, o_k[o1], b)
if o2 == 2 or o2 == 5:
p2 = "%d%s" % (c, o_k[o2]) + p1
else:
p2 = p1 + "%s%d" % (o_k[o2], c)
if o3 == 2 or o3 == 5:
p = "%d%s" % (d, o_k[o3]) + "(" + p2 + ")"
else:
p = "(" + p2 + ")" + "%s%d" % (o_k[o3], d)
res.append(p)
# (a o1 b) o3 (c o2 d)
X = [
(q[0], q[1], q[2], q[3]),
(q[0], q[2], q[1], q[3]),
(q[0], q[3], q[1], q[2]),
]
for a, b, c, d in X:
try:
result = o[o3](o[o1](a,b),o[o2](c,d))
except ZeroDivisionError:
continue
if abs(result - 10) < TOL:
if o1 == 2 or o1 == 5:
a, b = b, a
p1 = "(%d%s%d)" % (a, o_k[o1], b)
if o2 == 2 or o2 == 5:
c, d = d, c
p2 = "(%d%s%d)" % (c, o_k[o2], d)
if o3 == 2 or o3 == 5:
p = p2 + o_k[o3] + p1
else:
p = p1 + o_k[o3] + p2
res.append(p)
if verbose:
for r in res:
print r
if len(res) > 0:
return True
else:
return False
Ensuite, si vous calculez cela pour toutes les combinaisons de nombres,
import itertools
A = [''.join(i) for i in
itertools.combinations_with_replacement(
[str(x) for x in range(10)], 4)]
index_A = [make10(a, verbose=False) for a in A]
false = [a for i,a in enumerate(A) if not index_A[i]]
print len(false), false
Le résultat est
163 ['0000', '0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '0011', '0012', '0013', '0014', '0015', '0016', '0017', '0018', '0022', '0023', '0024', '0026', '0027', '0029', '0033', '0034', '0035', '0036', '0038', '0039', '0044', '0045', '0047', '0048', '0049', '0056', '0057', '0058', '0059', '0066', '0067', '0068', '0069', '0077', '0078', '0079', '0088', '0089', '0099', '0111', '0112', '0113', '0114', '0116', '0117', '0122', '0123', '0134', '0144', '0148', '0157', '0158', '0166', '0167', '0168', '0177', '0178', '0188', '0222', '0233', '0236', '0269', '0277', '0279', '0299', '0333', '0335', '0336', '0338', '0344', '0345', '0348', '0359', '0366', '0369', '0388', '0389', '0399', '0444', '0445', '0447', '0448', '0457', '0478', '0479', '0489', '0499', '0566', '0567', '0577', '0588', '0589', '0599', '0666', '0667', '0668', '0677', '0678', '0689', '0699', '0777', '0778', '0788', '0799', '0888', '1111', '1112', '1113', '1122', '1159', '1169', '1177', '1178', '1179', '1188', '1399', '1444', '1499', '1666', '1667', '1677', '1699', '1777', '2257', '3444', '3669', '3779', '3999', '4444', '4459', '4477', '4558', '4899', '4999', '5668', '5788', '5799', '5899', '6666', '6667', '6677', '6777', '6778', '6888', '6899', '6999', '7777', '7788', '7789', '7799', '7888', '7999', '8899']
Et à Wikipedia Le résultat est le même que celui qui a été répertorié.
Cela a pris environ 10 secondes pour le calcul itératif, mais maintenant c'est environ 2,5 secondes (même si c'est lent), et j'ai beaucoup appris sur la façon d'écrire des combinaisons et la notation inclusive. Vous pouvez augmenter le nombre d'opérateurs pour mettre la puissance et les journaux, ou vous pouvez mettre un espace et utiliser des nombres à 2 ou 3 chiffres au lieu de chaînes connectées.
Si vous avez des erreurs ou si vous souhaitez en faire plus, veuillez le signaler.
Recommended Posts