用SQL求解advent of code 2024年23题

原题地址 https://adventofcode.com/2024/day/23

第 23 天:局域网派对

当历史学家们在复活节兔子总部的安全区域闲逛时,你发现了今天计划举行的局域网派对的宣传海报!或许你能找到它;你连接到一个附近的数据链路端口,并下载了本地网络的地图(你的谜题输入)。

网络地图提供了每两台计算机之间的连接列表。例如:

复制代码
kh-tc
qp-kh
de-cg
ka-co
yn-aq
qp-ub
cg-tb
vc-aq
tb-ka
wh-tc
yn-cg
kh-ub
ta-co
de-co
tc-td
tb-wq
wh-td
ta-ka
td-qp
aq-cg
wq-ub
ub-vc
de-ta
wq-aq
wq-vc
wh-yn
ka-de
kh-ta
co-tc
wh-qp
tb-vc
td-yn

网络地图中的每一行文本代表一个连接;例如,行 kh-tc 表示名为 kh 的计算机和名为 tc 的计算机之间的连接。连接是无方向的;tc-kh 表示的意思完全相同。

局域网派对通常涉及多人游戏,所以也许你可以通过查找连接的计算机群来定位它。首先查找由三台计算机组成的集合,其中集合中的每台计算机都与其他两台计算机相连。

在这个例子中,有 12 个这样的三台互连计算机的集合:

复制代码
aq,cg,yn
aq,vc,wq
co,de,ka
co,de,ta
co,ka,ta
de,ka,ta
kh,qp,ub
qp,td,wh
tb,vc,wq
tc,td,wh
td,wh,yn
ub,vc,wq

如果首席历史学家在这里,并且他在局域网派对上,最好能马上知道。你相当确定他的计算机名称以 t 开头,因此只考虑那些至少有一台计算机名称以 t 开头的三台计算机集合。这将列表缩小到 7 个三台互连计算机的集合:

复制代码
co,de,ta
co,ka,ta
de,ka,ta
qp,td,wh
tb,vc,wq
tc,td,wh
td,wh,yn

找出所有三台互连计算机的集合。其中有多少个集合包含至少一台名称以 t 开头的计算机?

要开始,请获取你的谜题输入。


第二部分

结果还是太多,无法逐一查看。你必须用另一种方法找到局域网派对并亲自前往。

既然看起来没有任何员工在附近,你推测他们一定都在局域网派对上。如果真是这样,那么局域网派对将是所有计算机都相互连接的最大计算机集合。也就是说,对于局域网派对上的每台计算机,该计算机都与派对上的其他每台计算机有连接。

在上面的例子中,所有计算机都相互连接的最大集合由 co, de, kata 组成。该集合中的每台计算机都与集合中的其他每台计算机有连接:

复制代码
ka-co
ta-co
de-co
ta-ka
de-ta
ka-de

局域网派对的宣传海报上说,进入局域网派对的密码是派对上每台计算机的名称,按字母顺序排序,然后用逗号连接起来。(显然,运营局域网派对的是一群书呆子。)在这个例子中,密码将是 co,de,ka,ta

进入局域网派对的密码是什么?

我的解答如下

sql 复制代码
--第一部分

with tt as (from read_csv('2423-input.txt',header=0, delim='-')t(a, b) )
, tl as (from(select a, b from tt union all select b, a from tt) where a<b)
select distinct  t.a,t1.a,t1.b from tl t,tl t1 
where t.b=t1.a and
( t.a like 't%' or t1.a like 't%' or t1.b like 't%' )
and (t.a,t1.b) in (from  tl)
;
--第二部分

with recursive tt as (from read_csv('2423-input.txt',header=0, delim='-')t(a, b) )
, tl as (from(select a, b from tt union all select b, a from tt) where a<b)
,t as(select 1 lv,b, [a, b]g from tl
union all 
select distinct lv+1, tl.b, g||[tl.b]from t, tl where t.b=tl.a and len(g)= (select count(*) from unnest(g)g(b) where(g.b , tl.b)in(from  tl))
)
select listagg(g)from(select unnest(g)g from t where lv =(select max(lv) from t));

思路是从网络地图中提取出按机器名大小排列的连接列表,从此列表按照新增首部等于已有尾部多次递归连接,并检查新加入的机器满足和已有网络中每台机器都连接。

将检查条件len(g)= (select count(*) from unnest(g)g(b) where(g.b , tl.b)in(from tl))改为 not exists(select 1 from unnest(g)g(b) where(g.b , tl.b) not in(from tl))也可得到结果,效率都不太高。

相关推荐
rannn_1111 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
Bioinfo Guy1 小时前
高分Panel复现系列|转录因子网络太乱?用模块框把重点圈出来
数据库·生物信息学·生信可视化
数模竞赛Paid answer1 小时前
2026年华东杯数学建模B题医药物流安排问题解题全过程文档及程序
算法·数学建模·数据分析·华东杯
不会代码的小猴2 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
ltl3 小时前
Disaggregated DB 合集:Socrates、PolarDB、Taurus 的共同模式
数据库
AI备案指南-满满3 小时前
大模型与算法备案全流程详解:从零到通过的完整指南
人工智能·算法·备案·大模型备案·算法备案
江畔柳前堤3 小时前
LLM 训练核心机制深度解析:Warmup、Cosine Decay 与 Perplexity 的完整知识体系
网络·人工智能·深度学习·算法·机器学习·语音识别
一只旭宝3 小时前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法
良木林3 小时前
子串 - LeetCode hot 100
算法·leetcode·职场和发展