利用Duckdb求解Advent of Code 2021第9题 烟雾盆地

编程达人挑战赛·第5期 10w+人浏览 194人参与

原题地址

— 第9天:烟雾盆地 —

这些洞穴似乎是熔岩管。有些部分甚至仍然有火山活动;小的热液喷口将烟雾释放到洞穴中,烟雾像雨一样慢慢沉降。

如果你能模拟烟雾在洞穴中的流动方式,或许就能避开它,从而更加安全。潜艇为你生成了附近洞穴底部的高度图(你的谜题输入)。

烟雾会流向其所在区域的最低点。例如,考虑以下高度图:

2199943210
3987894921
9856789892
8767896789
9899965678

每个数字对应特定位置的高度,其中9是最高,0是该位置可能的最低高度。

你的第一个目标是找到低点——即低于其所有相邻位置的位置。大多数位置有四个相邻位置(上、下、左、右);地图边缘或角落的位置分别有三个或两个相邻位置。(对角线位置不计为相邻。)

在上面的例子中,有四个低点,都已高亮显示:两个在第一行(一个1和一个0),一个在第三行(一个5),一个在最底行(也是一个5)。高度图上的所有其他位置都有某个更低的相邻位置,因此不是低点。

一个低点的风险等级是1加上它的高度。在上面的例子中,这些低点的风险等级分别是2、1、6和6。因此,高度图中所有低点的风险等级总和为15。

找出你的高度图上的所有低点。你的高度图上所有低点的风险等级总和是多少?

你的谜题答案是 506。

此谜题的前半部分已完成!它提供了一颗金色星星:*

— 第二部分 —

接下来,你需要找到最大的盆地,以便知道哪些区域最需要避开。

一个盆地是指所有最终向下流向同一个低点的位置。因此,每个低点都有一个盆地,尽管有些盆地非常小。高度为9的位置不计入任何盆地,而所有其他位置总是恰好属于一个盆地。

盆地的大小是盆地内位置的数量,包括低点。上面的例子有四个盆地。

左上角的盆地,大小为3:

  99943210
 987894921
9856789892
8767896789
9899965678

右上角的盆地,大小为9:

21999 
398789 9 
985678989 
8767896789
9899965678

中间的盆地,大小为14:

2199943210
3987894921
9856789892
8767896789
9899965678

右下角的盆地,大小为9:

2199943210
3987894921
9856789 92
876789   9
98999 

找出三个最大的盆地,并将它们的大小相乘。在上面的例子中,这是 9 * 14 * 9 = 1134

如果将三个最大盆地的大小相乘,你会得到什么?

第一部分很简单,和2025年第4题相仿,找出比上下左右都小的数。即比它们的最小值还小。用行号差绝对值和列号差绝对值之和为1来确定上下左右,即只有一个方向差一。

with t as(select '
2199943210
3987894921
9856789892
8767896789
9899965678' t), 
b as(select row_number()over()rn,(rn-1)//10+1 r, (rn-1)%10+1 c,b::int b from(select unnest(string_split(replace(t,chr(10), ''), ''))b from t))
,c as(select b.b from b,b b2 where abs(b.r-b2.r)+abs(b.c-b2.c)=1 group by b.rn,b.b having min(b2.b) >b.b)
select sum(b+1) from c;

第二部分要找一个由9隔开的区域,标记属于一个盆地。它是一个封闭图形,外圈要么是边界,要么是9。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值