次の再帰的コード(関数count())が誤った計算回数を与える理由を理解するのは困っていますが、 count2())は、右のカウントを返します。 * 4 ^(n-1)?Pythonのset要素間に可能なすべての計算を再帰的に生成する
(この時点では、出力変数を気にしない。私が最初にこのパズルを解くことができれば、私は、後でそれを使用します。)
私はリストのための計算を作成することができ再帰関数を作成したいです任意の長さです。なぜなら、単純にループの入れ子にするだけでは十分ではありません。
import itertools
import operator
# http://stackoverflow.com/questions/2983139/assign-operator-to-variable-in-python
ops = {
0: operator.add,
1: operator.sub,
2: operator.mul,
3: operator.truediv
}
comb = [4, 1, 2, 3]
perms = list()
# itertools.permutations is not subscriptable, so this is a mandatory step.
# See e.g. http://stackoverflow.com/questions/216972/in-python-what-does-it-mean-if-an-object-is-subscriptable-or-not
# for details.
for i in itertools.permutations(comb):
perms.append(i)
output = list()
output2 = list()
# In theory, there are n! * 4^(n-1) possibilities for each set.
# In practice however some of these are redundant, because multiplication and
# addition are indifferent to calculation order. That's not tested here;
# nor is the possibility of division by zero.
# Variable debug is there just to enable checking the calculation count;
# it serves no other purpose.
debug = list()
debug2 = list()
def count(i):
for j in range(len(i)):
for op in ops:
if j+1 < len(i):
res = ops[op](i[j], i[j+1])
if j+2 < len(i):
ls = list(i[j+1:])
ls[0] = res
count(ls)
else:
debug.append([len(i), i[j], ops[op], i[j+1], res])
if res == 10: output.append(res)
def count2(i):
for j in range(len(i)):
for op in ops:
if j+1 < len(i):
res = ops[op](i[j], i[j+1])
for op2 in ops:
if j+2 < len(i):
res2 = ops[op2](res, i[j+2])
for op3 in ops:
if j+3 < len(i):
res3 = ops[op3](res2, i[j+3])
debug2.append(res3)
if res3 == 10: output2.append(res3)
for i in perms:
count(i)
count2(i)
print(len(debug)) # The result is 2400, which is wrong.
print(len(debug2)) # The result is 1536, which is correct.