比赛规则
有一张表 cards,id 是自增字段的数字主键,另外有4个字段 c1,c2,c3,c4 ,每个字段随机从 1~10 之间选择一个整数 要求选手使用一条 SQL 给出 24 点的计算公式,返回的内容示例如右图:
其中 result 字段是计算的表达式,只需返回1个解,如果没有解,result 返回null
测试数据与验证步骤
1.进入NineData官网(www.ninedata.cloud),注册并登录ninedata
2.申请一个免费的 mysql demo 数据库
3.在 SQL 窗口中查看 cards 表数据:select * from poker24.cards
2023.12.28 ~
收集候选人收件地址,奖品发放
1. 24 点的计算规则:只能使用加减乘除四则运算,不能使用阶乘、指数等运算符,每个数字最少使用一次,且只能使用一次,可以使用小括号改变优先级
2. 只能使用一条 SQL ,可以使用数据库内置函数,但是不能使用存储过程/自定义函数和代码块。
3. SQL 正确性大家在 NineData 平台 demo 数据库自己验证,或在自己的数据库上验证,组委会评测服务器是 4 核 CPU ,32 GB 内存
4. 选手个人诚信参赛,不允许提交别人的比赛代码,如果发现有类似代码,工作组以第一个提交的为有效参赛
5. 每个选手最多提交 3 次比赛代码
6. 提交的 SQL 不能超过 10 KB大小
备注:
评委阵容
获奖选手
第1名 郑凌云
淘宝,负责推荐系统开发
综合得分:95
思路说明
核心:因为4张牌计算24点时的顺序可任意互换,所以不同排列的4张牌可视为同一组合。采用质数编码,把1到10映射成2到29内的质数,4张牌的积可作为该组合的唯一编码
1. 本地写代码,通过简单的回溯算法,生成24点游戏的所有解:
152,((1+1)+1)*8,156,(6*2)*(1+1),...
2. 受限于代码大小10k限制,通过把上一步生成的数据进行压缩:
SELECT REPLACE(TO_BASE64(COMPRESS('152,((1+1)+1)*8,156,(6*2)*(1+1),...')), '\n', '')
3. 提交的代码中,先对上一步生成的数据解压缩:UNCOMPRESS(FROM_BASE64('XXXX')),并通过递归CTE生成查询表:152,((1+1)+1)*8;156,(6*2)*(1+1);...
4. 对输入表LEFT JOIN上一步生成的查询表,关联的键值是对c1,c2,c3,c4做质数编码后的积。
思路说明
1. 采取查表法,预先用其他方法((grubbyoo 编写的SQL ,552条6秒) (C语言566条0.3秒))生成4个数四则运算能算出24点的组合,包括点数从小到大排序拼接成字符串和输出结果,把它保存在SQL的CTE表中备查。
2. 为了解决采用拼接union select或values()的长度超过10K字节限制的问题,主要采取了压缩空间的技巧。
3. 解决测试数据和已知结论对应关系。cards表包含数字1到10的全排列,共10000种。
4. 接下来的优化点主要在于建立更高效的关联字段。