利用Duckdb求解Advent of Code 2022第4题 重叠营地

编程达人挑战赛·第5期 5.7w人浏览 102人参与

原题地址

第 4 天:营地清理

在最后一批补给从船上卸下之前,需要清理出空间,因此几位精灵被分配了清理营地部分区域的工作。每个区域都有一个唯一的 ID 号,每个精灵被分配了一段区域 ID 范围。

然而,当一些精灵互相比较他们的区域分配时,他们注意到许多分配是重叠的。为了快速找到重叠部分并减少重复劳动,精灵们两两配对,并为每对制作了一个区域分配的大列表(你的谜题输入)。

例如,考虑以下区域分配对列表:

2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8

对于前几对,这个列表的意思是:

  • 在第一对精灵中,第一个精灵被分配了区域 2-4(区域 2、3 和 4),而第二个精灵被分配了区域 6-8(区域 6、7、8)。
  • 第二对中的每个精灵被分配了两个区域。
  • 第三对中的每个精灵被分配了三个区域:一个得到了区域 5、6 和 7,而另一个也得到了区域 7,加上 8 和 9。

这个例子列表使用个位数的区域 ID 以便于绘制;你的实际列表可能包含更大的数字。直观上看,这些区域分配对看起来像这样:

.234.....  2-4
.....678.  6-8

.23......  2-3
...45....  4-5

....567..  5-7
......789  7-9

.2345678.  2-8
..34567..  3-7

.....6...  6-6
...456...  4-6

.23456...  2-6
...45678.  4-8

一些配对注意到,其中一个分配完全包含了另一个。例如,2-8 完全包含了 3-7,而 6-6 完全被 4-6 包含。在一个分配完全包含另一个的配对中,配对中的一个精灵将专门清理其伙伴已经要清理的区域,所以这些似乎是最需要重新考虑的。在这个例子中,有 2 个这样的配对。

在多少个分配对中,其中一个范围完全包含另一个?


第二部分

似乎仍然有相当多的重复工作计划。相反,精灵们想知道有多少对分配有任何重叠

在上面的例子中,前两对(2-4,6-8 和 2-3,4-5)没有重叠,而剩下的四对(5-7,7-9、2-8,3-7、6-6,4-6 和 2-6,4-8)确实有重叠:

  • 5-7,7-9 在一个区域上重叠:区域 7。
  • 2-8,3-7 在所有区域 3 到 7 上重叠。
  • 6-6,4-6 在一个区域上重叠:区域 6。
  • 2-6,4-8 在区域 4、5 和 6 上重叠。

所以,在这个例子中,重叠的分配对数量是 4

在多少个分配对中,范围有重叠?

这道题很简单,就是求两个区间的重叠部分,第一部分是求一个完全包含另一个的情况,第二部分是求交集不为0。
sql如下:

with t as(select '2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8'
t),
b as(select unnest(string_split(t,chr(10)))b from t),
c as(select [x::int for x in string_split(replace(b,'-',','),',')]b from b)
select count(*) from c where greatest(b[1], b[3])<= least( b[2], b[4]);
--select count(*) from c where b[1]<=b[3] and b[2]>=b[4] or b[1]>=b[3] and b[2]<=b[4];

上述代码计算第二部分,把最后一行替换成注释掉的行就能计算第一部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值