用python算24点及原理详解

2023-11-03

1 描述

给出4个正整数,使用加、减、乘、除4种运算以及括号把4个数连接起来得到一个结果等于24的表达式。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

注:这里加、减、乘、除以及括号的运算结果和运算优先级跟平常定义一致。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬

例如,对于5,5,5,1,可知 5× (5-1/5) = 24。又如,对于 1,1,4,2 无论如何都不能得到24

1.1 输入格式

在代码中的输入部分输入4个正整数。

1.2 输出格式

对于每一组测试数据,如果可以得到24,输出"YES"其算法;否则输出“NO”。

2 大致思路

将四个数字进行全排列,在他们之间添加运算符号,最后将数字和操作符进行拼接运算。

运算符我们需要进行排列组合,因为只有四个数字,所以只需要三个运算符,而且算法符可能会重复,比如三个都是+。

再遍历四个数字的全排列,对每一组数字而言,遍历所有组合的操作符。最后将数字和操作符进行拼接运算,就可以得到最终结果了。

3 知识点补充

1、首先我们对所有数字进行去全排列,这里我们使用 itertools.permutations 来帮助我们完成。

iertools.permutations 用法演示

import itertools

a = int(input("请输入第1个数字:"))
b = int(input("请输入第2个数字:"))
c = int(input("请输入第3个数字:"))
d = int(input("请输入第4个数字:"))

my_list = [a, b, c, d]
result = [c for c in itertools.permutations(my_list, 4)]

for i, r in enumerate(result):
    if i % 4 == 0:
        print()
    print(r, end="\t")
print("\n\n长度为:", len(result))

运行结果:

请输入第1个数字:1
请输入第2个数字:2
请输入第3个数字:3
请输入第4个数字:4

(1, 2, 3, 4)	(1, 2, 4, 3)	(1, 3, 2, 4)	(1, 3, 4, 2)	
(1, 4, 2, 3)	(1, 4, 3, 2)	(2, 1, 3, 4)	(2, 1, 4, 3)	
(2, 3, 1, 4)	(2, 3, 4, 1)	(2, 4, 1, 3)	(2, 4, 3, 1)	
(3, 1, 2, 4)	(3, 1, 4, 2)	(3, 2, 1, 4)	(3, 2, 4, 1)	
(3, 4, 1, 2)	(3, 4, 2, 1)	(4, 1, 2, 3)	(4, 1, 3, 2)	
(4, 2, 1, 3)	(4, 2, 3, 1)	(4, 3, 1, 2)	(4, 3, 2, 1)	

长度为: 24

4 具体代码

from itertools import permutations

a = int(input("请输入第1个数字:"))
b = int(input("请输入第2个数字:"))
c = int(input("请输入第3个数字:"))
d = int(input("请输入第4个数字:"))
my_list = [a, b, c, d]
# 对4个整数随机排列的列表
result = [c for c in permutations(my_list, 4)]

symbols = ["+", "-", "*", "/"]

list2 = []  # 算出24的排列组合的列表

flag = False

for one, two, three, four in result:
    for s1 in symbols:
        for s2 in symbols:
            for s3 in symbols:
                if s1 + s2 + s3 == "+++" or s1 + s2 + s3 == "***":
                    express = ["{0}{1}{2}{3}{4}{5}{6}".format(one, s1, two, s2, three, s3, four)]  # 全加或者乘时,括号已经没有意义。
                else:
                    express = ["(({0}{1}{2}){3}{4}){5}{6}".format(one, s1, two, s2, three, s3, four),
                               "({0}{1}{2}){3}({4}{5}{6})".format(one, s1, two, s2, three, s3, four),
                               "(({0}{1}({2}{3}{4})){5}{6})".format(one, s1, two, s2, three, s3, four),
                               "{0}{1}(({2}{3}{4}){5}{6})".format(one, s1, two, s2, three, s3, four),
                               "{0}{1}({2}{3}({4}{5}{6}))".format(one, s1, two, s2, three, s3, four)]

                for e in express:
                    try:
                        if eval(e) == 24:
                            list2.append(e)
                            flag = True
                    except ZeroDivisionError:
                        pass

list3 = set(list2)  # 去除重复项

for c in list3:
    print("YES:", c)

if not flag:
    print("NO!")

 5 BUG修复

感谢qq_44273902博主提出程序BUG,现进行BUG修复

5.1 问题分析

5.1.1 问题复现

输入3、3、8、8,进行问题复现

输出结果如下: 

针对输出结果进行分析,明明是有正确答案的,为何还输出NO!???

5.1.2 原因分析

运行以下代码流程

print(8/(3-(8/3)))

运行结果:

 

了然,精度问题

5.2 针对问题进行解决

既然是由于精度问题造成的,那么可以约定保留6位小数点(当然也可以保留其他位数的小数),如此一来即可解决该问题。

将第36行代码

if eval(e) == 24:

改成

if round(eval(e), 6) == 24:

优化之后的代码如下:

from itertools import permutations

a = int(input("请输入第1个数字:"))
b = int(input("请输入第2个数字:"))
c = int(input("请输入第3个数字:"))
d = int(input("请输入第4个数字:"))
my_list = [a, b, c, d]
# 对4个整数随机排列的列表
result = [c for c in permutations(my_list, 4)]

symbols = ["+", "-", "*", "/"]

list2 = []  # 算出24的排列组合的列表

flag = False
print(result)

for one, two, three, four in result:
    for s1 in symbols:
        for s2 in symbols:
            for s3 in symbols:
                if s1 + s2 + s3 == "+++" or s1 + s2 + s3 == "***":
                    express = ["{0}{1}{2}{3}{4}{5}{6}".format(one, s1, two, s2, three, s3, four)]  # 全加或者乘时,括号已经没有意义。
                else:
                    express = ["(({0}{1}{2}){3}{4}){5}{6}".format(one, s1, two, s2, three, s3, four),
                               "({0}{1}{2}){3}({4}{5}{6})".format(one, s1, two, s2, three, s3, four),
                               "(({0}{1}({2}{3}{4})){5}{6})".format(one, s1, two, s2, three, s3, four),
                               "{0}{1}(({2}{3}{4}){5}{6})".format(one, s1, two, s2, three, s3, four),
                               "{0}{1}({2}{3}({4}{5}{6}))".format(one, s1, two, s2, three, s3, four)]
                # print(one + two + three + four)
                    if str(one) + str(two) + str(three) + str(four) == "8383":
                        print(express)

                for e in express:
                    try:
                        # if eval(e) == 24:
                        if round(eval(e), 6) == 24:
                            list2.append(e)
                            flag = True
                    except ZeroDivisionError:
                        pass

list3 = set(list2)  # 去除重复项

for c in list3:
    print("YES:", c)

if not flag:
    print("NO!")

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用python算24点及原理详解 的相关文章

随机推荐

  • 文献标志码

    发表日期 2005年1月29日 编辑录入 webmaster 1 中图分类号 这是在投向中国国内杂志时经常要用到的一个号码 编辑一般要你自己提供 目前国内大部分图书馆均采用 中国图书馆分类法 第四版 作为馆藏分类体系 因此上你所在的图书馆问
  • MySQL-存储过程-函数-触发器-游标

    一 介绍 以往我们使用数据库都是基于SQL去完成数据的CRUD 但其实 SQL是可编程的 我们可以把他当做一门编程语言一样去使用它 在其中我们可以 声明变量 执行SQL 进行逻辑判断 循环等等操作 为了达成这个目标 我们需要学习 存储过程
  • 机器学习入门方法推荐(少走弯路)入门视频推荐

    入门可以看看下列的几个课程 第一第二个公认的经典了 1 首先当然是吴恩达的经典机器学习了 可以在万能的b站搜 也可以在网易公开课搜 吴恩达机器学习 http study 163 com course courseMain htm cours
  • 比kettle好用的开源etl_ETL常用的三种工具

    ETL 是英文 Extract Transform Load 的缩写 用来描述将数据从来源端经过抽取 extract 转换 transform 加载 load 至目的端的过程 数据仓库结构 通俗的说法就是从数据源抽取数据出来 进行清洗加工转
  • 性能指标分析

    一 用户事务分析 用户事务分析是站在用户角度进行的基础性能分析 1 Transation Sunmmary 事务综述 对事务进行综合分析是性能分析的第一步 通过分析测试时间内用户事务的成功与失败情况 可以直接判断出系统是否运行正常 2 Av
  • Python序列以及切片操作

    1 序列 序列是一个用于存储多个值的连续空间 每个值都对应一个整数编号 称为索引 序列结构主要有列表 元组 集合 字典和字符串 2 索引 正向递增索引 取值范围 0 N 1 反向递减索引 取值范围 1 N 下面我们用索引遍历一下字符串序列
  • 头歌课堂练习5:进程的同步与互斥

    第一关 多线程编程 创建多线程的函数pthread create原型如下 pthread create pthread t tidp const pthread attr t attr void start rtn void void ar
  • Python编写一个函数cacluate, 可以接收任意多个数,返回的是一个元组.元组的第一个值为所有参数的平均值, 第二个值是大于平均值的所有数

    编写一个函数cacluate 可以接收任意多个数 返回的是一个元组 元组的第一个值为所有参数的平均值 第二个值是大于平均值的所有数 详细代码见链接 共同学习 加油 文末有知识点分析 文章所使用的知识点if lese语句 if 条件1 pri
  • js+mysql实现论坛回复功能_php实现简单BBS论坛及回复

    实例简介 该资源主要参考http blog csdn net eastmount article details 44241583文章 讲述了如何通过PHP实现论坛搭建简单的效果 同时包括IFrame实现局部布局 后台数据库通过SAE搭建
  • 2022年 软件工程专业 计算机组成原理 运算器实验报告

    年级 班号 组号 学号 专业 软件工程 日期 2022 年 5 月 11日 姓名 预判你的代码 实验名称 运算器 实验室 实验 目的 或 要求 1 了解运算器的组成结构 2 掌握运算器的工作原理 3 熟悉运算器的设计方法 4 掌握运算器的控
  • AndroidManifest.xml文件综合详解

    http www cnblogs com hnrainll archive 2011 10 26 2225710 html 一 重要性AndroidManifest xml是Android应用程序中最重要的文件之一 它是Android程序的
  • Zend Studio 12 安装及破解

    1 安装 1 1 下载最新版本Zend Studio 12 0 0 http downloads zend com studio eclipse 12 0 0 ZendStudio 12 0 0 win32 win32 x86 msi 12
  • Android10填坑适配指南,实际经验代码,拒绝翻译

    Android10填坑适配指南 包含实际经验代码 绝不照搬翻译文档 1 Region Op相关异常 java lang IllegalArgumentException Invalid Region Op only INTERSECT an
  • 2021年南京天印中学高考成绩查询,2021年南京高中录取分数线是多少及高中排名榜...

    2020年南京的高中录取分数线都已经公布 以下是小编给大家整理的汇总信息 仅供参考 一 2020年南京高中录取分数线是多少 一 科技特长生 学科特长生 科技特长生和学科特长生投档控制线均为548分 二 普通高中指标生 原市区普通高中指标生录
  • STM32——超声波模块

    模块介绍 超声波模块一般使用的都是HC SR04来进行测距 1 产品特点 HC SR04 超声波测距模块可提供 2cm 400cm 的非接触式距离感测功能 测 距精度可达高到的非接触式距离感测功能 测距精度可达高到 3mm 模块包括超声波发
  • 期货用期权对冲(期货用期权对冲吗)

    怎么用期权 option 做对冲 hedge 在期权交易市场中 对冲期权风险可以通过交易不同的合约方向 使用组合策略对自己合约盈利或者合约的亏损进行一个风险对冲 这样可以降低期权交易市场中的风险 在期权交易市场中 投资者一般也会将期权用作对
  • Java 静态变量,静态方法,静态常量简介说明

    转自 Java 静态变量 静态方法 静态常量简介说明 下文笔者将着重讲述静态的相关说明 如下所示 实现思路 当我们在方法 变量 常量前面加上static关键字 则可认为其是一个静态的对象 静态方法注意事项 静态方法不可以使用this关键字
  • 去AV片马赛克,开发者被抓了

    来源丨程序员软件库 怎么去除图片或者视频上的马赛克 自从马赛克这玩意被弄出来后 让大家悲喜交加 你想在社交软件上发一些图片或者视频 有部分比较隐私的东西 那就需要使用马赛克技术遮挡下 保护下自己隐私或者别人隐私是非常好的 比如 新闻在拍摄报
  • python爬取美女图片

    需求 最近对python爬虫感兴趣 于是也依葫芦画瓢试着用爬虫爬取之前喜欢的网站上的美女图片 网站 http www mm131 com xinggan 其中每一套图都是一张一个页面 存一套图如果是手动得点翻几十个页面 但现在用爬虫的话 就
  • 用python算24点及原理详解

    1 描述 给出4个正整数 使用加 减 乘 除4种运算以及括号把4个数连接起来得到一个结果等于24的表达式 注 这里加 减 乘 除以及括号的运算结果和运算优先级跟平常定义一致 例如 对于5 5 5 1 可知 5 5 1 5 24 又如 对于