163点的规则如下:从一副去掉大王小王的扑克牌中抽出六张,A,J,Q,K视为1,11,12,13,用这6张牌经过有理数的加减乘除运算(过程中可以出现分数)且每张牌都用到的情况下,要求满足结果等于163。无需输入,输出一个数字表示方案数。
import random
import itertools
# 一副牌 不带大小王
list1 = [i for i in range(1, 14)] * 4
# 随机抽六张牌放list2里边 可重复抽取
list2 = random.sample(list1, 6)
# 将这六张排列,并去掉重复的组合
list3 = list(set(list(itertools.permutations(list2, 6))))
# 六个数要运算五次
list4 = ['+', '-', '*', '/'] * 5
# 抽取5个运算符号排列组合,并去重
list5 = list(set(list(itertools.permutations(list4, 5))))
n = 0
# 遍历6张牌所有可能的顺序
for i in list3:
# 第一张牌的值为a
a = i[0]
# 遍历五个运算符所有可能的情况(共4的五次方=1024种可能)
for j in list5:
# 每种可能需要五次计算
for k in range(5):
if j[k] == '+':
a += i[k + 1]
elif j[k] == '-':
a -= i[k + 1]
elif j[k] == '*':
a *= i[k + 1]
elif j[k] == '/':
a /= i[k + 1]
if a == 163:
n += 1
# 循环变量初始化
a = i[0]
# 输出六张牌
print(list2)
# 输出对应的总方案数
print(n)

还有一个细节问题,就是关于运算过程中可能出现的分数,
经测试,如果产生形如7/3的无限位数的小数,在python中的乘除运算也是可逆的。即7/3之后再乘以3计算,得到的不会是一个同样那么长的小数。这就避免了可能造成的结果方案遗漏。
print(7/3)
x = 7/3
print(x*3)
