news 2026/2/15 22:56:59

利用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/2/3 10:09:25

大数据毕设项目:基于机器学习的房子价值预测系统的设计与实现(源码+文档,讲解、调试运行,定制等)

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

作者头像 李华
网站建设 2026/2/10 4:17:09

大数据毕设选题推荐:基于python的机器学习房价预测可视化系统基于机器学习的房子价值预测系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】

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

作者头像 李华
网站建设 2026/2/7 5:32:43

阿里拿38K出来的大佬良心分享,熬夜整理10 万字详细Java面试笔记!

国内的互联网面试&#xff0c;恐怕是现存的、最接近科举考试的制度。这是由于互联网IT行业的求职者太多了&#xff0c;如果考察的是清一溜的算法题和设计题&#xff0c;那么会要求面试官有极高的技术水平&#xff0c;还要花大量的时间成本和精力。所以&#xff0c;八股文面试也…

作者头像 李华
网站建设 2026/2/14 2:00:46

SSM293的农家乐系统-住宿-美食-活动vue

目录SSM293农家乐系统概述住宿管理模块美食预订模块活动预约模块技术实现与优势开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;SSM293农家乐系统概述 SSM293农家乐系统基于Vue.js前端框架开发&#xff0c;整合住宿管理、美食预…

作者头像 李华
网站建设 2026/2/15 6:52:06

全网最全专科生必备TOP8 AI论文写作软件测评

全网最全专科生必备TOP8 AI论文写作软件测评 2026年专科生必备AI论文写作软件测评&#xff1a;为何需要这份榜单&#xff1f; 随着人工智能技术的不断发展&#xff0c;越来越多的学术辅助工具涌现出来&#xff0c;为学生和研究人员提供了高效、便捷的写作支持。对于专科生而言&…

作者头像 李华
网站建设 2026/2/11 11:06:38

SSM280的课程智能组卷考试系统vue

目录SSM280课程智能组卷考试系统&#xff08;Vue版&#xff09;摘要开发技术源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;SSM280课程智能组卷考试系统&#xff08;Vue版&#xff09;摘要 SSM280课程智能组卷考试系统是基于SpringSpr…

作者头像 李华