Ich glaube, ich habe gespielt, um 10 zu machen, indem ich mir die Nummer des entgegenkommenden Autos angesehen habe, z. B. wenn ich in einem Auto bin, und addiere, subtrahiere, multipliziere und teile, aber manchmal gibt es ein schwieriges Problem Sie müssen etwas tun, bevor Sie fortfahren. Außerdem frage ich mich, wie viele Kombinationen ich nicht lösen kann. Probieren wir also alle vier 0-9-Zahlenpaare und Operatorkombinationen aus und schreiben ein Programm, um die Ergebnisse anzuzeigen.
Verweise:
Die dritte Referenzstelle befindet sich in Python. Da die Formel jedoch in eine Zeichenfolge konvertiert und an die eval-Funktion übergeben wird, wird die Ausführungsgeschwindigkeit extrem langsam (Programmier-FAQ - Python 2.7ja1-Dokumentation:. Siehe Programmierung.html # id20)). Wie in der zweiten Referenzstelle gezeigt, sind die Operatoren daher sechs Operatoren mit einer Unterscheidung in der Reihenfolge der Subtraktion und Division. Das ist,
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]
Erstellen Sie eine Liste der Operatoren als. Der Operator wird dreimal verwendet, vorausgesetzt, a, b, c, d sind Zahlen und o1, o2, o3 sind Operatoren.
((a o1 b) o2 c) o3 d ・ ・ ・ 1 (a o1 b) o3 (c o2 d) ・ ・ ・ 2
Es gibt nur zwei Möglichkeiten.
Es gibt 4! = 24 Möglichkeiten, a, b, c, d auszuwählen, aber wenn 1, werden Duplikate mit a und b ersetzt, sodass 24/2 = 12 Möglichkeiten zur Auswahl stehen. Wenn Sie wie folgt schreiben, listet die Liste "X" alle Fälle aus der Zeichenfolge "q" (wie "1337") auf, mit Ausnahme doppelter Zahlen (wie "3" in "1337"). Kann in gespeichert werden.
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)
Im Fall von 2 ist es nicht notwendig, über die Kombination von a und b, die Kombination von c und d und die Kombination von (a, b) und (c, d) nachzudenken. Wenn Sie also über die drei möglichen Anordnungen von Zahlen nachdenken, Ich weiß, dass es gut ist. Da die Anzahl klein ist, ist es möglicherweise einfacher zu verstehen, wenn Sie solide schreiben, anstatt über Kombinationen nachzudenken.
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]),
]
Bei der Auswahl von o1 werden 6 Dinge 3 Stellen zugewiesen, daher sollten 6 3 = 216 Möglichkeiten in Betracht gezogen werden.
from itertools import product
O = [i for i in product(range(6), repeat=3)]
So können Sie alle Kombinationen machen.
Danach können Sie für alle Kombinationen von O den Inhalt von X für die beiden Muster berechnen und das Muster aufzeichnen, das 10 wird. Zu diesem Zeitpunkt wird ZeroDivisionError angezeigt, sodass Sie die Ausnahme behandeln müssen. Ich habe die Antwort in eine Zeichenfolge konvertiert, damit sie leicht zu sehen ist. Aufgrund der Beschaffenheit des Computers können auch einige Fehler auftreten. Daher haben wir beschlossen, einen Fehler mit einer Zahl (0,001) zuzulassen, die kleiner ist als die Zahl, die durch Teilen von 1 durch 9 durch die 3. Potenz (= 0,0013717421124828531 ...) erhalten wird.
Die tatsächlich hergestellte ist unten gezeigt. Da es auf dem IPython Notebook ausgeführt wurde, ist es nur eine Funktionsdefinition.
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
Wenn Sie dies für alle Zahlenkombinationen berechnen,
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
Ergebnis ist
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']
Und zu Wikipedia Das Ergebnis ist das gleiche wie das, was aufgelistet wurde.
Die iterative Berechnung dauerte ungefähr 10 Sekunden, aber jetzt sind es ungefähr 2,5 Sekunden (obwohl es langsam ist), und ich habe viel darüber gelernt, wie man Kombinationen und inklusive Notationen schreibt. Sie können die Anzahl der Operatoren erhöhen, um Strom und Protokolle zu speichern, oder Sie können ein Leerzeichen einfügen und 2- oder 3-stellige Zahlen anstelle von verbundenen Zeichenfolgen verwenden.
Wenn Sie Fehler haben oder mehr tun möchten, weisen Sie bitte darauf hin.
Recommended Posts