Advent of Code 2025 挑战全手写代码 Day 7 - 实验室

35 阅读3分钟

🎄Advent of Code 2025 挑战全手写代码 Day 7 - 实验室


周末好!今天题目 Laboratories,难度中等(⭐⭐⭐),主要考察:数组集合运算动态规划

advent-of-code-2025-day-7

📖 题目速览

题目地址: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)  # 所有可能终点的路径数之和

💡 算法亮点

  1. 集合运算优化:用 set 存储分束器位置,交集运算 O(1),比遍历查找快得多
  2. 动态规划思想:Part 2 本质是路径计数 DP,每个位置的状态由前一状态转移而来
  3. 空间优化:只存储有分束器的行,节省内存
  4. 边界处理:左右移动时检查边界,避免越界

这题完美展示了从经典到量子的思维转换! Part 1 是确定性的,Part 2 是概率性的,简直就是量子计算的简化版!

完整代码:访问 github

Happy Coding! 量子实验室的冒险告一段落,我们的旅程已经过半,继续加油!🚀 day-7-ranking