扬州国土资源局网站开发区分局,台州模板网建站,建网站的方法,wordpress管理员破解这是DBatUTuebingen发布的。 源地址#xff1a;https://github.com/DBatUTuebingen/Advent_of_Code Advent of Code 2021 第9天
烟雾盆地
输入解析和低点计算放在共享文件 smoke-basin.sql 中#xff08;通过 .read 引入#xff09;#xff0c;两部分都会用到。
第一部分…这是DBatUTuebingen发布的。源地址https://github.com/DBatUTuebingen/Advent_of_CodeAdvent of Code 2021 第9天烟雾盆地输入解析和低点计算放在共享文件smoke-basin.sql中通过.read引入两部分都会用到。第一部分用法$ duckdb smoke-basin-part1.sql ┌────────────┐ │ risk level │ │ int128 │ ├────────────┤ │ 526 │ └────────────┘ 运行时间秒实际 0.000 用户 0.000190 系统 0.000082第二部分递归CTEflows本质上计算了二维洞穴网格上的连通分量分量由高度为9的网格点分隔。关键优化仅从第一部分找到的低点开始搜索连通分量而不是从所有网格点开始。参见递归CTEflows的初始查询q₀中cave和lowpoints的半连接。用法在我的Mac Book Pro M2上大约需要30秒。$ duckdb smoke-basin-part2.sql ┌─────────┐ │ sizes │ │ int32 │ ├─────────┤ │ 1123524 │ └─────────┘ 运行时间秒实际 30.636 用户 23.693674 系统 6.924345-- AoC 2021, Day 9 (Part 2)-- AoC 输入文件DROPMACROIFEXISTSinput;CREATEMACRO input()ASinput.txt;-- 引入共享的SQL文件包含高度图解析和低点计算.readsmoke-basin.sql-- 开启计时器并设置单线程运行确保结果确定性.timeronSETthreads1;WITHRECURSIVE-- 1. 为每个网格点分配一个唯一的盆地编号basin初始为行号cave(x,y,height,basin)AS(SELECTh.x,h.y,h.height,ROW_NUMBER()OVER()ASbasinFROMheightmapASh),-- 2. 递归CTE模拟水流扩散确定每个点属于哪个盆地flows(x,y,basin)AS(-- 初始查询仅从低点开始扩散优化关键SELECTc.x,c.y,c.basinFROMcaveASc SEMIJOINlowpointsASlpON(c.y,c.x)(lp.y,lp.x)UNIONALL-- 递归部分从已访问点向四个相邻点扩散SELECTc.x,c.y,LEAST(f.basin,c.basin)ASbasinFROMflowsASf,caveAScWHERE(c.x,c.y)IN((f.x1,f.y),(f.x-1,f.y),(f.x,f.y1),(f.x,f.y-1))ANDc.height9-- 只扩散到高度小于9的点高度9为边界),-- 3. 确定每个点的最终盆地编号取扩散过程中遇到的最小编号basins(x,y,basin)AS(SELECTf.x,f.y,MIN(f.basin)ASbasinFROMflowsASfGROUPBYf.y,f.x)-- 4. 计算前三大盆地大小的乘积SELECTPRODUCT(b.size)::intASsizesFROM(SELECTCOUNT(*)ASsizeFROMbasinsASbGROUPBYb.basin-- 按盆地分组统计大小ORDERBYsizeDESC-- 按大小降序排序LIMIT3)ASb;-- 取最大的三个盆地SQL代码分析注释caveCTE为每个网格点(x, y)分配一个唯一的初始盆地编号basin使用ROW_NUMBER()。这为后续的盆地合并提供了初始标识。flows递归CTE初始查询只从低点lowpoints开始扩散这是性能优化的关键避免从所有点开始搜索。递归查询从已访问点向四个方向上、下、左、右扩散但只扩散到高度 9的点因为高度9是盆地边界。LEAST(f.basin, c.basin)在扩散过程中始终保留遇到的最小盆地编号确保同一盆地的所有点最终有相同编号。basinsCTE对flows的结果按点(x, y)分组取最小的basin编号作为该点的最终盆地归属。最终查询统计每个盆地的大小点数。按大小降序排序取前三大的盆地。使用PRODUCT()函数计算这三个大小的乘积。结果转换为int类型输出。算法思路总结该SQL通过递归CTE实现了基于低点的洪水填充算法Flood Fill从每个低点开始向四周扩散直到遇到高度9的边界。扩散过程中合并盆地编号确保同一盆地使用最小编号。最后统计各盆地大小计算最大三个的乘积。优化点在于仅从低点开始扩散避免了从所有点开始的不必要计算大幅提升了性能。