原题地址 。
— 第 7 天:实验室 —
你感谢了头足类动物的帮助,离开了垃圾压缩机,发现自己身处北极研究区熟悉的走廊中。
根据一个写着"传送器中心"的大标志,他们似乎在研究传送;你忍不住自己尝试了一下,踏上了那个巨大的黄色传送器平台。
突然,你发现自己在一个陌生的房间里!这个房间没有门;唯一的出路就是传送器。不幸的是,传送器似乎在泄漏魔法烟雾。
由于这是一个传送器实验室,周围散落着许多备用零件、手册和诊断设备。连接上一个诊断工具后,它很有帮助地显示了错误代码 0H-N0,这显然意味着其中一个快子歧管出现了问题。
你很快找到了快子歧管的图表(你的谜题输入)。一束快子束从标记为 S 的位置进入歧管;快子束总是向下移动。快子束可以自由通过空的空间(.)。然而,如果快子束遇到一个分离器(^),光束会停止;取而代之的是,从分离器的紧邻左侧和紧邻右侧各自继续发出一束新的快子束。
例如:
.......S.......
...............
.......^.......
...............
......^.^......
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
...............
在这个例子中,入射的快子束(|)从 S 向下延伸,直到遇到第一个分离器:
.......S.......
.......|.......
.......^.......
...............
......^.^......
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
...............
此时,原始光束停止,从分离器发射出两束新光束:
.......S.......
.......|.......
......|^|......
...............
......^.^......
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
...............
这些光束继续向下,直到遇到更多分离器:
.......S.......
.......|.......
......|^|......
......|.|......
......^.^......
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
...............
此时,两个分离器总共只产生三束快子束,因为它们都把快子注入到它们之间的同一位置:
.......S.......
.......|.......
......|^|......
......|.|......
.....|^|^|.....
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
...............
这个过程一直持续,直到所有快子束都到达分离器或离开歧管:
.......S.......
.......|.......
......|^|......
......|.|......
.....|^|^|.....
.....|.|.|.....
....|^|^|^|....
....|.|.|.|....
...|^|^|||^|...
...|.|.|||.|...
..|^|^|||^|^|..
..|.|.|||.|.|..
.|^|||^||.||^|.
.|.|||.||.||.|.
|^|^|^|^|^|||^|
|.|.|.|.|.|||.|
为了修复传送器,你首先需要了解快子歧管的光束分离特性。在这个例子中,快子束总共被分离了 21 次。
分析你的歧管图表。光束将被分离多少次?
你的谜题答案是 1658。
此谜题的第一部分已完成!它提供了一颗金星:*
— 第二部分 —
完成对歧管的分析后,你开始修复传送器。然而,当你打开传送器的侧面更换损坏的歧管时,你惊讶地发现这不是一个经典的快子歧管——它是一个量子快子歧管。
使用量子快子歧管时,只有单个快子粒子被送入歧管。快子粒子会同时走每个遇到的分离器的左路径和右路径。
由于这不可能实现,手册推荐了量子快子分离的多世界诠释:每当一个粒子到达分离器时,实际上时间本身发生了分裂。在一个时间线中,粒子向左走;在另一个时间线中,粒子向右走。
为了修复歧管,你真正需要知道的是一个单粒子完成其所有可能的旅程后,有多少个时间线是活跃的。
在上面的例子中,存在许多时间线。例如,有一个粒子总是向左走的时间线:
.......S.......
.......|.......
......|^.......
......|........
.....|^.^......
.....|.........
....|^.^.^.....
....|..........
...|^.^...^....
...|...........
..|^.^...^.^...
..|............
.|^...^.....^..
.|.............
|^.^.^.^.^...^.
|..............
或者,有一个粒子在每个分离器处交替向左和向右走的时间线:
.......S.......
.......|.......
......|^.......
......|........
......^|^......
.......|.......
.....^|^.^.....
......|........
....^.^|..^....
.......|.......
...^.^.|.^.^...
.......|.......
..^...^|....^..
.......|.......
.^.^.^|^.^...^.
......|........
或者,有一个粒子最终到达与交替时间线相同的点,但走了一条完全不同的路径到达那里的时间线:
.......S.......
.......|.......
......|^.......
......|........
.....|^.^......
.....|.........
....|^.^.^.....
....|..........
....^|^...^....
.....|.........
...^.^|..^.^...
......|........
..^..|^.....^..
.....|.........
.^.^.^|^.^...^.
......|........
在这个例子中,粒子最终总共有 40 个不同的时间线。
将量子快子分离的多世界诠释应用到你的歧管图表上。一个单粒子最终会出现在多少个不同的时间线上?
解题思路,
第一问,看起来很像一个异或操作,快子和分离器两个1在同一个列相遇变成0,0和0还是0,后来仔细一看不是异或,因为我要0遇到1还是0,请教DeepSeek后它给出了正确的操作表达式:x & (~y)
SQL如下:
with recursive t as(
select
'.......S.......
...............
.......^.......
...............
......^.^......
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
...............' t)
, b as(select row_number()over()rn ,translate(b, '.S^', '011') b from(select unnest(string_split(t, chr(10)))b from t)where instr(b, 'S')>0 or instr(b, '^')>0)
,a as(select 1 lv, b::BITSTRING::int m from b where rn=1
union all
select 1+lv, m & ~( b::BITSTRING::int)| (b::BITSTRING::int <<1) |(b::BITSTRING::int >>1) from a, b
where lv+1=rn)
, o as(select lv, m::bitstring v,bit_count(v)bc from a)
, p as(select lv, v, bc, lead(v)over(order by lv)&v l ,bit_count(l)bc2 from o)
select sum(bc)-sum(bc2) from p where l is not null;
对于示例数据,它正确得出了分裂次数21, 但是正式输入数据一行有140字符,超过了DuckDB的hugeint范围,所以让DeepSeek把上述SQL改写成Python程序,修改几处BUG后如下所示。
它添加的注释很好地说明了算法,就不多解释了。
# 原 SQL 中的递归 CTE 部分用循环和列表处理来模拟
# 1. 原始数据
data = """.......S.......
...............
.......^.......
...............
......^.^......
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
..............."""
# 2. 将数据按行分割,并转换为二进制整数
lines = data.split('\n')
# 处理每一行:将 '.'、'S'、'^' 转换为二进制数字
# 规则:'.' -> 0, 'S'/'^' -> 1
binary_rows = []
for line in lines:
if 'S' in line or '^' in line:
bin_str = line.replace('.', '0').replace('S', '1').replace('^', '1')
binary_rows.append(int(bin_str, 2)) # 转换为整数
# 3. 模拟递归计算(实际上是逐行迭代计算)
lv = 1
m = binary_rows[0] # 第一行
results = [(lv, m, bin(m))] # 存储每行结果 (层级, 整数, 二进制字符串)
# 处理第 2 行到最后行
for i in range(1, len(binary_rows)): # 确保不超过数据行数
lv += 1
b = binary_rows[i] # 当前行的二进制整数
# 核心公式: m & ~b | (b << 1) | (b >> 1)
m = (m & ~b) | (b << 1) | (b >> 1)
results.append((lv, m, bin(m)))
# 4. 计算 bc (bit_count) 和 bc2
from math import log2
def bit_count(num):
"""计算整数的二进制表示中 1 的个数"""
return bin(num).count('1')
# 将结果转换为便于处理的列表
o = [(lv, v, bit_count(v)) for lv, v, _ in results]
# print(o)
# 计算相邻两行之间的重叠比特数
total_bc = 0
total_bc2 = 0
for i in range(len(o) - 1):
lv, v, bc = o[i]
next_lv, next_v, next_bc = o[i + 1]
# 当前行与下一行的位与结果
l = v & next_v
bc2 = bit_count(l)
total_bc += bc
total_bc2 += bc2
# 5. 最终计算结果
result = total_bc - total_bc2
print(f"结果: {result}")
将它用于正式输入,通过了。

1万+

被折叠的 条评论
为什么被折叠?



