news 2026/4/23 18:51:35

利用DeepSeek辅助DuckDB SQL求解Advent of Code 2025第10题 电子工厂

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
利用DeepSeek辅助DuckDB SQL求解Advent of Code 2025第10题 电子工厂

前期嫌SQL处理麻烦和性能不足,用python做过一个,
最近看到clickhouse微信公众号文章用纯 SQL 硬刚 Advent of Code?ClickHouse 把「不可能」变成了 12 天的现实。
看到了希望,所以用DuckDB SQL重新做过。

第一部分格式转换代码如下,都是自己完成的:

withrecursive tas(select'[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7} [...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2} [.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}'t),bas(selectrow_number()over()rn,reverse(substr(b,2,instr(b,']')-2))b1,--信号灯字符串,格式.##.,注意要翻转字符串substr(b,instr(b,']')+2,instr(b,'{')-3-instr(b,']'))b2,--按钮字符串,格式(3) (1,3) (2) (2,3) (0,2) (0,1)substr(b,instr(b,'{')+1,instr(b,'}')-1-instr(b,'{'))b3,--伏特字符串,格式3,5,4,7translate(b1,'#.','10')::bit::intb1a,--转二进制位再转整数list_reduce([0]||string_split(unnest(string_split(replace(replace(b2,')',''),'(',''),' ')),',')::int[],lambda x,y :(x+(1<<y)))b2a,--按钮转成整数列表string_split(b3,',')::int[]b3a,from(selectunnest(string_split(t,chr(10)))bfromt)),das(selectrn,b1a,array_agg(b2a)a,b3afrombgroupbyall)fromdorderbyrn;

示例数据子查询d的结果如下

┌───────┬───────┬──────────────────────┬────────────────────────┐ │ rn │ b1a │ a │ b3a │ │ int64 │ int32 │ int32[] │ int32[] │ ├───────┼───────┼──────────────────────┼────────────────────────┤ │ 1 │ 6 │ [8, 10, 4, 12, 5, 3] │ [3, 5, 4, 7] │ │ 2 │ 8 │ [29, 12, 17, 7, 30] │ [7, 5, 12, 7, 2] │ │ 3 │ 46 │ [31, 25, 55, 6] │ [10, 11, 11, 5, 10, 5] │ └───────┴───────┴──────────────────────┴────────────────────────┘

一开始没注意信号灯字符串从左到右是从低位到高位,没做翻转,导致算错了b1a。

┌───────┬───────┬──────────────────────┬────────────────────────┐ │ rn │ b1a │ a │ b3a │ │ int64 │ int32 │ int32[] │ int32[] │ ├───────┼───────┼──────────────────────┼────────────────────────┤ │ 1 │ 6 │ [8, 10, 4, 12, 5, 3] │ [3, 5, 4, 7] │ │ 2 │ 2 │ [29, 12, 17, 7, 30] │ [7, 5, 12, 7, 2] │ │ 3 │ 29 │ [31, 25, 55, 6] │ [10, 11, 11, 5, 10, 5] │ └───────┴───────┴──────────────────────┴────────────────────────┘

DeepSeek辅助完成将每行按钮的各种组合求出。

我有一个数组a,包含n个元素,请用duckdb语法编写一句SQL,输出数组a的全部子集,比如[1,3]输出[],[1],[3],[1,3],

可以使用 DuckDB 的UNNEST配合WITH RECURSIVE递归生成子集。以下是 SQL 语句:

WITHRECURSIVE subsetsAS(-- 初始:空子集SELECT[]ASsubset,1ASlevelUNIONALL-- 递归:逐个添加元素SELECTarray_append(subset,a.val)ASsubset,level+1ASlevelFROMsubsets,UNNEST([1,3])WITHORDINALITYASa(val,idx)WHEREa.idx>=level)SELECTsubsetFROMsubsetsORDERBYcardinality(subset),subset;

如果不需要递归,也可以直接使用GENERATE_SERIES配合位运算:

WITHarrAS(SELECT[1,3]ASa)SELECT(SELECTarray_agg(a[i])FROMgenerate_series(1,array_length(a))ASiWHERE(bitpos>>(i-1))&1=1)ASsubsetFROMarr,generate_series(0,(1<<array_length(a))-1)ASbits(bitpos);

两种方法都可以输出所有子集:

  • []
  • [1]
  • [3]
  • [1, 3]

你可以根据 DuckDB 的版本和性能需求选择合适的方法。第一种递归方法更直观,第二种位运算方法通常性能更好。

我选的是第二种,如下语句把每种组合的两两异或结果算出,然后与要求的数比较。

,sas(SELECTrn,bitpos,b1a,(SELECTarray_agg(a[i])FROMgenerate_series(1,array_length(a))t(i)WHERE(bitpos>>(i-1))&1=1)ASsubsetFROMd,generate_series(1,(1<<array_length(a))-1)ASbits(bitpos))selectrn,b1a,bitpos,subset,bit_count(bitpos)fromswherelist_reduce(subset,lambda x,y :xor(x,y))=b1aorderbyrn,5;

结果如下,按压次数最少的组合已标记。

┌───────┬───────┬────────┬──────────────────┬───────────────────┐ │ rn │ b1a │ bitpos │ subset │ bit_count(bitpos) │ │ int64 │ int32 │ int64 │ int32[] │ int8 │ ├───────┼───────┼────────┼──────────────────┼───────────────────┤ │ 1 │ 6 │ 48 │ [5, 3] │ 2 │<-- │ 1 │ 6 │ 10 │ [10, 12] │ 2 │ │ 1 │ 6 │ 7 │ [8, 10, 4] │ 3 │ │ 1 │ 6 │ 61 │ [8, 4, 12, 5, 3] │ 5 │ │ 2 │ 8 │ 28 │ [17, 7, 30] │ 3 │<-- │ 2 │ 8 │ 27 │ [29, 12, 7, 30] │ 4 │ │ 3 │ 46 │ 6 │ [25, 55] │ 2 │<-- │ 3 │ 46 │ 13 │ [31, 55, 6] │ 3 │ └───────┴───────┴────────┴──────────────────┴───────────────────┘

最后按原始行号分组求最小值,再加总。

selectsum(minstep)from(selectrn,min(bit_count(bitpos))minstep--按压组合二进制数的1的个数就是按压次数fromswherelist_reduce(subset,lambda x,y :xor(x,y))=b1agroupbyrn);

对于示例数据,结果如下,和题目给出的一致

┌──────────────┐ │ sum(minstep) │ │ int128 │ ├──────────────┤ │ 7 │ └──────────────┘

对于我的正式测试数据,结果和用时如下,不算太快

┌──────────────┐ │ sum(minstep) │ │ int128 │ ├──────────────┤ │ 527 │ └──────────────┘ Run Time (s): real 0.328 user 1.588000 sys 0.052000

这里发现Advent of Code的测试题库也是有重复的,这个结果和clickhouse公众号的一致。

理论上本题用递归更合适,因为要求最少按压次数,只要求出一个解就可以退出迭代了,而全组合是穷举。第二部分题目的数据量不可能用穷举解决。

再用第一种方法试做一遍,直接使用DeepSeek的语句报错

Binder Error: Cardinality can only operate on MAPs

去掉cardinality函数输出如下,有多余的[3, 3]

┌─────────┐ │ subset │ │ int32[] │ ├─────────┤ │ [] │ │ [1] │ │ [3] │ │ [1, 3] │ │ [3, 3] │ └─────────┘

需要改成如下,规定后加的元素索引必须要大于前面最后一个的索引,不允许重复使用,才能得到正确结果。

WITHRECURSIVE subsetsAS(-- 初始:空子集SELECT[]ASsubset,1ASlevel,0lastidxUNIONALL-- 递归:逐个添加元素SELECTarray_append(subset,a.val)ASsubset,level+1ASlevel,idxFROMsubsets,UNNEST([1,2,3])WITHORDINALITYASa(val,idx)WHEREa.idx>lastidx)SELECTsubsetFROMsubsets;┌───────────┐ │ subset │ │ int32[]│ ├───────────┤ │[]│ │[1]│ │[2]│ │[3]│ │[1,2]│ │[1,3]│ │[2,3]│ │[1,2,3]│ └───────────┘

再结合本题的业务逻辑,找到就不再迭代。

,subsetsAS(-- 初始:空子集SELECTrn,[]ss,0xor_val,0ASlevel,0lastidxfromdUNIONALL-- 递归:逐个添加元素SELECTs.rn,ss||[a.val],xor(xor_val,a.val),level+1ASlevel,idxFROMsubsets s,d,unnest(a)WITHORDINALITYASa(val,idx)WHEREa.idx>lastidxands.rn=d.rnandnotexists(select1fromd d1wherexor_val=b1aands.rn=d1.rn))SELECTs.rn,xor_val,level,ssFROMsubsets s,d d1wherexor_val=b1aands.rn=d1.rnorderbys.rn,level;┌───────┬─────────┬───────┬──────────────────┐ │ rn │ xor_val │level│ ss │ │ int64 │ int32 │ int32 │ int32[]│ ├───────┼─────────┼───────┼──────────────────┤ │162[5,3]<--162[10,12]│ │163[8,10,4]│ │165[8,4,12,5,3]│ │283[17,7,30]<--284[29,12,7,30]│ │3462[25,55]<--3463[31,55,6]│ └───────┴─────────┴───────┴──────────────────┘

和前面穷举的结果完全一致。按原始行号分组求最小值,再加总。

,ras(SELECTs.rn,xor_val,level,ssFROMsubsets s,d d1wherexor_val=b1aands.rn=d1.rnorderbys.rn,level)selectsum(minl)from(selectrn,min(level)minlfromrgroupbyrn);┌───────────┐ │sum(minl)│ │ int128 │ ├───────────┤ │7│ └───────────┘

使用正式测试数据,用时反而更长

┌───────────┐ │ sum(minl) │ │ int128 │ ├───────────┤ │ 527 │ └───────────┘ Run Time (s): real 0.633 user 1.632000 sys 0.312000

尝试去掉不必要的ss,将a和b1a的数据带入subset查询,减少一次表连接,仍然不如穷举,可能是递归中not exists检查还是做了表连接的原因。

Run Time (s): real 0.472 user 1.252000 sys 0.152000

最后加了一个found标记,用分析函数找出当前rn中是否有找到的,消除not exists检查,快了。

,subsetsAS(-- 初始:空子集SELECTrn,a,b1a,0found,0xor_val,0ASlevel,0lastidxfromdUNIONALL-- 递归:逐个添加元素SELECTs.rn,s.a,s.b1a,max(s.xor_val=s.b1a)over(partitionbys.rn),xor(xor_val,a.val),level+1ASlevel,idxFROMsubsets s,unnest(a)WITHORDINALITYASa(val,idx)WHEREa.idx>lastidxandnotfound),ras(SELECTs.rn,xor_val,levelFROMsubsets swherexor_val=b1aorderbys.rn,level)selectsum(minl)from(selectrn,min(level)minlfromrgroupbyrn);┌───────────┐ │sum(minl)│ │ int128 │ ├───────────┤ │527│ └───────────┘ RunTime(s):real0.236user0.608000sys0.152000

看了一下clickhouse第一部分的解法,也是穷举。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:27:07

psql 中的流水线操作(PostgreSQL 18)

原文地址 https://postgresql.verite.pro/blog/2025/10/01/psql-pipeline.html psql 中的流水线操作&#xff08;PostgreSQL 18&#xff09; 2025 年 10 月 1 日 Postgres 中的流水线是什么&#xff1f; 流水线是网络协议支持的一种客户端特性&#xff0c;其核心思想是&#xf…

作者头像 李华
网站建设 2026/4/23 15:28:05

【课程设计/毕业设计】基于Python的智能房价分析与预测系统基于django的城市房产价值的数据分析与预测系统的设计与实现【附源码、数据库、万字文档】

java毕业设计-基于springboot的(源码LW部署文档全bao远程调试代码讲解等) 博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、…

作者头像 李华
网站建设 2026/4/23 12:13:40

大数据计算机毕设之基于Python Django 的全国房价大数据可视化系统基于django的城市房产价值的数据分析与预测系统的设计与实现(完整前后端代码+说明文档+LW,调试定制等)

java毕业设计-基于springboot的(源码LW部署文档全bao远程调试代码讲解等) 博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、…

作者头像 李华
网站建设 2026/4/23 12:57:04

9个降AI率工具推荐!继续教育学生必看

9个降AI率工具推荐&#xff01;继续教育学生必看 AI降重工具&#xff1a;让论文更自然&#xff0c;更安心 在当前的学术环境中&#xff0c;越来越多的学生开始关注“**论文降AIGC率**”和“**去AI痕迹**”的问题。随着AI写作工具的普及&#xff0c;许多论文在内容上虽然逻辑清晰…

作者头像 李华
网站建设 2026/4/23 14:34:20

大数据计算机毕设之基于hadoop的山东瓜果蔬菜分析系统(完整前后端代码+说明文档+LW,调试定制等)

java毕业设计-基于springboot的(源码LW部署文档全bao远程调试代码讲解等) 博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、…

作者头像 李华
网站建设 2026/4/23 14:05:53

年终运维愁?塔能智慧照明让总结计划秒变“神助攻”!

一、年终总结“凭经验”&#xff0c;来年计划“拍脑袋”&#xff1f;你不是一个人!临近岁末年初之时&#xff0c;各地市政工程管理处、城市照明管理中心、园区物业以及商业楼宇的运维负责人都在忙于撰写年度总结并且制定新一年的工作计划&#xff0c;可是一个较为普遍的难题出现…

作者头像 李华