🎄Advent of Code 2025 挑战全手写代码 Day 7 - 实验室
周末好!今天题目 Laboratories,难度中等(⭐⭐⭐),主要考察:数组、集合运算、动态规划。
📖 题目速览
题目地址:adventofcode.com/2025/day/7
传送器故障?量子流形?多世界解释?这剧情比科幻小说还刺激! 从垃圾场出来直接跳到量子实验室,这波操作我给满分!
👀 题目大意
Part 1:经典快子束传播
- 快子束从
S点向下传播 - 遇到分束器
^时,光束停止,左右各产生一条新光束 - 问:总共分裂多少次?
Part 2:量子快子束传播(多世界解释)
- 单个快子粒子在分束器处必须选择走左右两条路径中的一条
- 每次选择都创造新的时间线
- 问:最终有多少条不同的时间线?
🧠 脑洞时刻
这题简直就是量子计算的入门教程!Part 1 是经典物理,Part 2 是量子物理。
Part 1 的核心思路:
- 用集合存储当前行所有光束的位置
- 用集合交集快速找到需要分裂的位置
- 每次分裂,光束向左右扩散,计数器 +1
Part 2 的核心思路:
- 这是典型的动态规划问题!
paths[i]表示到达位置 i 的路径数量- 遇到分束器时,路径数向左右分配:
new_paths[left] += paths[current] - 最终返回所有位置的路径数之和
✨ 代码精华
# Part 1: 经典光束模拟
def part1(self) -> int:
out: int = 0
current: set[int] = {self.start_point}
for splitter_row in self.splitters:
# 集合交集:找到需要分裂的光束位置
intersection: set[int] = current & splitter_row
if not intersection:
continue
new_current: set[int] = set()
for idx in current:
if idx in intersection:
# 分裂!左右各一条新光束
if idx - 1 >= 0:
new_current.add(idx - 1)
if idx + 1 < self.width:
new_current.add(idx + 1)
out += 1 # 计数器 +1
else:
# 直行
new_current.add(idx)
current = new_current
return out
# Part 2: 量子路径计数(动态规划)
def part2(self) -> int:
current: set[int] = {self.start_point}
paths: list[int] = [0] * self.width
paths[self.start_point] = 1 # 起点有一条路径
for splitter_row in self.splitters:
intersection: set[int] = current & splitter_row
if not intersection:
continue
new_current: set[int] = set()
new_paths: list[int] = [0] * self.width
for idx in current:
if idx in intersection:
# 量子分裂:路径数向左右分配
if idx - 1 >= 0:
new_current.add(idx - 1)
new_paths[idx - 1] += paths[idx] # 左路径继承当前路径数
if idx + 1 < self.width:
new_current.add(idx + 1)
new_paths[idx + 1] += paths[idx] # 右路径继承当前路径数
else:
# 直行:路径数不变
new_current.add(idx)
new_paths[idx] += paths[idx]
current = new_current
paths = new_paths
return sum(paths) # 所有可能终点的路径数之和
💡 算法亮点:
- 集合运算优化:用
set存储分束器位置,交集运算 O(1),比遍历查找快得多 - 动态规划思想:Part 2 本质是路径计数 DP,每个位置的状态由前一状态转移而来
- 空间优化:只存储有分束器的行,节省内存
- 边界处理:左右移动时检查边界,避免越界
这题完美展示了从经典到量子的思维转换! Part 1 是确定性的,Part 2 是概率性的,简直就是量子计算的简化版!
完整代码:访问 github
Happy Coding! 量子实验室的冒险告一段落,我们的旅程已经过半,继续加油!🚀