【Python】Advent Of Code 2025代码实录

引子

Advent Of Code是一个年度编程习题活动,每年都会出一些编程题,今年也来试试。可以通过这里参与。

不给出题目的详细描述啦~

我的代码已经开源到https://github.com/coder109/Advent-Of-Code-2025

最后几道题没时间做了,有机会再补吧,有点小难。

1-1:旋转结果为0的次数

我们的任务是这样的,给定一个0-99标号的转盘,初始位置在50,随后通过不断地旋转改变它的位置,求取这个过程在指向0的次数。

这道题的考点就在于对负数取模的操作,这道题的重点是:负数的取模。在Python中,一个数的模是:
$$
\text{MOD} = N-nK
$$
其中,我们要求的式子是:
$$
\text{MOD} = N % K
$$
所以这道题的思路很简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
with open("1.input", "r") as f:
content = f.readlines()

initial_position = 50
count = 0
for line in content:
if line[0] == "R":
initial_position += int(line[1:])
elif line[0] == "L":
initial_position -= int(line[1:])
initial_position = initial_position % 100
if initial_position == 0:
count += 1

print(count)

也就是说,每次我们只需要旋转,然后对100取模得到实际的位置即可。

1-2:旋转过程中经过0的次数

这道题的思路就要麻烦一些,我们要统计在旋转过程中指向0的次数,比如从50开始,右转550圈,那么就指向了6次0点,我们要统计全部的指向0的次数。那么,我们的思想可以是这样的:

  1. 计算当前位置和0之间的距离。
  2. 如果旋转的距离大于这个距离,那么就一定指到0了,否则就不用考虑指向0的过程。

那么代码就如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if __name__ == "__main__":
with open("1.input", "r") as f:
content = f.readlines()

position = 50
count = 0
for line in content:
position_to_zero_distance = position if line[0] == "L" else (100 - position)
spin_distance = int(line[1:])
if spin_distance >= position_to_zero_distance:
count += (spin_distance - position_to_zero_distance) // 100 + 1
if line[0] == "R":
position += spin_distance
elif line[0] == "L":
position -= spin_distance

position = position % 100

print(count)

我们的思路是这样的,对于与0之间的距离的计算,我们分为两个情况,如果向左旋转,那就是postion本身,如果向右转,就是100-position,随后我们判断经过0的次数,最后更新position即可。

到这里,我们的结果是6239,结果不对,这是为什么?我们忘记考虑0这个边界条件了!当当前的位置为0时,不论向左向右,我们的与0的距离都是100,而不是0。所以我们要对我们的代码做一点更新:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if __name__ == "__main__":
with open("1.input", "r") as f:
content = f.readlines()

position = 50
count = 0
for line in content:
position_to_zero_distance = position if line[0] == "L" else (100 - position)
# Update
if position_to_zero_distance == 0:
position_to_zero_distance = 100
spin_distance = int(line[1:])
if spin_distance >= position_to_zero_distance:
count += (spin_distance - position_to_zero_distance) // 100 + 1
if line[0] == "R":
position += spin_distance
elif line[0] == "L":
position -= spin_distance

position = position % 100

print(count)

此题通过。

2-1:重复模式的匹配简单版

我们给定了一系列数字的范围,让我们求取这个过程中所有满足条件的数字的和,所谓的条件是这样的,如果一个数字是由两个相同的部分组成的,就算作满足条件,比如11、22、1230612306等。

这道题当然可以用正则匹配、字符串匹配之类的方法做,且更简单,但是这次我们用数论的方法来做。

我们首先能看出来,这样的数字肯定是偶数长度的,否则不可能写作两个相同部分。那么还有什么特点呢,这样的数字实际上满足这样的性质,假设我们的数字有$2N$位,那么这个数字就可以被$10\cdots01$这个数整除,这个数字中0的个数就等于$N-1$,且商为前/后半个$N$位数字。这个证明实在是没有难度,故此略去。

所以,我们的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
with open("2.input", "r") as f:
content = f.readlines()

def str_to_valid(num: str):
digit_num = len(num)
if digit_num % 2 == 1:
return True
division = 10 ** (digit_num / 2) + 1
return int(num) % division != 0

for line in content:
id_list = line.split(",")
res = 0.
for id_elem in id_list:
from_id, to_id = id_elem.split("-")
for i in range(int(from_id), int(to_id) + 1):
if not str_to_valid(str(i)):
res += i
print(res)

2-2:重复模式的匹配复杂版

现在我们的目标变了,目的是匹配多次重复的数字,不仅仅是两次,现在123051230512305这种数字也是要匹配到的了。这一次数论的知识貌似不管用了,我们来试一下字符串匹配的机制。我们要做的是一件很简单的事,对于一个长度为$L$的数字,我们要从1位开始切分到$\lfloor\frac{L}{2}\rfloor$位,然后看其它的部分是不是和这一个部分是同样的,如果都是同样的,那么就表明这个数字是来自于某个数字重复得成的,否则,如果有一个部分是不相同的,那么就接着迭代。如果没有一次迭代成功,那么就不需要被匹配到,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
with open("2.input", "r") as f:
content = f.readlines()

def str_to_valid(num: str):
if len(num) == 1:
return True
for cut_elem_len in range(1, len(num) // 2 + 1):
pattern = num[:cut_elem_len]
is_good = False
for target_idx in range(cut_elem_len, len(num), cut_elem_len):
if num[target_idx:target_idx + cut_elem_len] != pattern:
is_good = True
if not is_good:
return False
return True

for line in content:
id_list = line.split(",")
res = 0.
for id_elem in id_list:
from_id, to_id = id_elem.split("-")
for i in range(int(from_id), int(to_id) + 1):
if not str_to_valid(str(i)):
res += i
print(res)

3-1:寻找最大数字的二位子串

我们被给定了一些全是数字的字符串,我们要寻找这里面最大的数字,比如987654321,就是98,897654321,就是97,对于一个数字,其左边的数字在给定字符串中,必须要出现在右边数字的左边。这道题很直觉的是,十位数大,那就是真的大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
with open("3.input", "r") as f:
content = f.readlines()

def find_max_in_line(line: str):
max_val, max_idx = -1, -1
for i in range(len(line)):
if int(line[i]) > max_val:
max_val = int(line[i])
max_idx = i
return max_val, max_idx

result = 0
for line in content:
line = line.strip()
first_large, first_idx = find_max_in_line(line)
if first_idx == len(line) - 1:
second_large, second_idx = find_max_in_line(line[:first_idx])
result += second_large * 10 + first_large
else:
second_large, second_idx = find_max_in_line(line[first_idx+1:])
result += first_large * 10 + second_large

print(result)

其思想是,首先寻找最大的数字,如果这个数字出现在末尾,就表明它只能当作个位的数字,否则就可以当作十位的数字。

3-2:寻找最大数字的十二位子串

这道题的思路和上一道题有一定的差别,对于这个12位数,我们不能按照第一题的思想来了,而是需要这样思考:12位数的第一位,可以在序列的第一位到从最后开始数起的第11位里取,因为第一位大,那么整个数字就大,不必考虑后续。所以代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
with open("3.input", "r") as f:
content = f.readlines()

def find_max_in_line(line: str):
max_val, max_idx = -1, -1
for i in range(len(line)):
if int(line[i]) > max_val:
max_val = int(line[i])
max_idx = i
return max_val, max_idx

result = 0
for line in content:
line = line.strip()
temp_result = 0
first_idx = 0
for idx in range(12):
first_large, tmp_first_idx = find_max_in_line(line[first_idx:-11 + idx if idx-11 != 0 else None])
if first_large == -1:
first_large = int(line[first_idx])
tmp_first_idx = 0
first_idx = first_idx + tmp_first_idx + 1
temp_result = temp_result * 10 + first_large
result += temp_result

print(result)

这里有一点是,对于Python来说,[:-1]是不包括最后一位的,而[:0]是无意义的,所以说要在这里做一个判断,如果find_max_in_line()返回了-1,就表明输入序列为0长度,idx-11first_idx是重合的,需要注意。

4-1:寻找邻近格子元素少于4的元素个数

这道题给定了一个图,每个格子有一个“纸卷”,我们要找到周围邻近八个格子纸卷数少于4个的纸卷个数,那么这道题就直接判断即可,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
with open("4.input", "r") as f:
content = f.readlines()

height, width = len(content), len(content[0].strip())

graph = [[0 for _ in range(width+2)] for _ in range(height+2)]

result = 0

for h_idx in range(1, height+1):
for w_idx in range(1, width+1):
curr_item = content[h_idx-1][w_idx-1]
if curr_item == "@":
graph[h_idx][w_idx] = 1

for h_idx in range(1, height+1):
for w_idx in range(1, width+1):
if graph[h_idx][w_idx] == 0:
continue
adjacent_num = 0
if graph[h_idx-1][w_idx] == 1:
adjacent_num += 1
if graph[h_idx+1][w_idx] == 1:
adjacent_num += 1
if graph[h_idx][w_idx-1] == 1:
adjacent_num += 1
if graph[h_idx][w_idx+1] == 1:
adjacent_num += 1
if graph[h_idx+1][w_idx+1] == 1:
adjacent_num += 1
if graph[h_idx+1][w_idx-1] == 1:
adjacent_num += 1
if graph[h_idx-1][w_idx+1] == 1:
adjacent_num += 1
if graph[h_idx-1][w_idx-1] == 1:
adjacent_num += 1
if adjacent_num < 4:
result += 1
print(result)

最后的一大堆if是AI生成,省时省力。

4-2:全部能挪走的元素

在挪走可以挪走的元素(邻近小于4的元素)之后,我们可以挪走更多的元素,那么最后能挪走多少?这便是题干要求,模拟即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
with open("4.input", "r") as f:
content = f.readlines()

height, width = len(content), len(content[0].strip())

graph = [[0 for _ in range(width+2)] for _ in range(height+2)]

total_result = 0
result = 0


for h_idx in range(1, height+1):
for w_idx in range(1, width+1):
curr_item = content[h_idx-1][w_idx-1]
if curr_item == "@":
graph[h_idx][w_idx] = 1

while True:
result = 0
mem_list = []


for h_idx in range(1, height+1):
for w_idx in range(1, width+1):
if graph[h_idx][w_idx] == 0:
continue
adjacent_num = 0
if graph[h_idx-1][w_idx] == 1:
adjacent_num += 1
if graph[h_idx+1][w_idx] == 1:
adjacent_num += 1
if graph[h_idx][w_idx-1] == 1:
adjacent_num += 1
if graph[h_idx][w_idx+1] == 1:
adjacent_num += 1
if graph[h_idx+1][w_idx+1] == 1:
adjacent_num += 1
if graph[h_idx+1][w_idx-1] == 1:
adjacent_num += 1
if graph[h_idx-1][w_idx+1] == 1:
adjacent_num += 1
if graph[h_idx-1][w_idx-1] == 1:
adjacent_num += 1
if adjacent_num < 4:
result += 1
mem_list.append([h_idx, w_idx])
if result == 0:
break
for mem in mem_list:
graph[mem[0]][mem[1]] = 0
total_result += result


print(total_result)

5-1:区间判断

我们被给定了一些区间和一些数字,我们要判断数字是否在所有区间的并集中。第一个问可以直接去除重复的区间,然后进行判断:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
with open("5.input", "r") as f:
content = f.readlines()

range_list, num_list = [], []

num_mode = False
for line in content:
if len(line.strip()) == 0:
num_mode = True
continue
if num_mode:
num_list.append(int(line.strip()))
else:
range_start, range_end = [int(x) for x in line.strip().split("-")]
range_list.append([range_start, range_end])

# Build Range Tree
range_list = sorted(range_list, key=lambda x: x[0])
sanitized_range_list = [range_list[0]]
# Remove Overlapping Ranges
for range_idx in range(1, len(range_list)):
curr_elem = range_list[range_idx]
curr_start, last_end = curr_elem[0], sanitized_range_list[-1][1]
if curr_start > last_end:
sanitized_range_list.append(curr_elem)
elif curr_start == last_end:
sanitized_range_list[-1][1] = curr_elem[1]
else:
sanitized_range_list[-1][1] = max(curr_elem[1], last_end)

num_list = sorted(num_list)
valid_count = 0
for num in num_list:
for range_elem in sanitized_range_list:
if range_elem[0] <= num <= range_elem[1]:
valid_count += 1
break

print(valid_count)

实际上,第三个循环可以进行优化。

5-2:区间并集的数字个数

第二题实际上很简单,就是计算我们在第一题中求出的共同区间的所有数字个数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
with open("5.input", "r") as f:
content = f.readlines()

range_list, num_list = [], []

for line in content:
if len(line.strip()) == 0:
break
range_start, range_end = [int(x) for x in line.strip().split("-")]
range_list.append([range_start, range_end])

# Build Range Tree
range_list = sorted(range_list, key=lambda x: x[0])
sanitized_range_list = [range_list[0]]
# Remove Overlapping Range
for range_idx in range(1, len(range_list)):
curr_elem = range_list[range_idx]
curr_start, last_end = curr_elem[0], sanitized_range_list[-1][1]
if curr_start > last_end:
sanitized_range_list.append(curr_elem)
elif curr_start == last_end:
sanitized_range_list[-1][1] = curr_elem[1]
else:
sanitized_range_list[-1][1] = max(curr_elem[1], last_end)

valid_count = 0
for range_elem in sanitized_range_list:
valid_count += range_elem[1] - range_elem[0] + 1

print(valid_count)

6-1:所有运算的加和

这道题就是求每一列的运算结果的和。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
with open("6.input", "r") as f:
content = f.readlines()

operate_list, num_list_list = [], []
for line in content:
line_elem = line.strip().split(" ")
remove_list = []
for idx in range(len(line_elem)):
if len(line_elem[idx].strip()) == 0:
remove_list.append(idx)

for idx in sorted(remove_list, reverse=True):
del line_elem[idx]
if "*" in line_elem:
operate_list = line_elem
else:
num_list_list.append(line_elem)

result = 0
for idx, operation in enumerate(operate_list):
temp_result = 0
if operation == "*":
temp_result = 1
for num_list in num_list_list:
temp_result *= int(num_list[idx])
elif operation == "+":
for num_list in num_list_list:
temp_result += int(num_list[idx])
else:
print(operation)
raise NotImplementedError
result += temp_result

print(result)

6-2:数字变成竖着写的啦!

这道题的每个列的数字变成竖着写的了,要求我们取每一列的数字组成一个新的数字进行运算。这道题的关键在于,每个数字如今要竖着看的话,就表明我们首先需要将它们对齐,然后竖着取数字。那么首先,我们容易想到这样一个规律,就是在每一行中都按顺序遍历,如果过一个位,每行都是空格,就表明我们读取完毕了一个数字。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
with open("6.input", "r") as f:
content = f.readlines()

for content_idx in range(len(content)):
content[content_idx] = content[content_idx][:-1]


def add_num_buffer(num_buffer: list[str], op: str) -> int:
result = 0 if op == '+' else 1
idx = 0
while idx < len(num_buffer[0]):
curr_result = ""
for line in num_buffer:
curr_result += "" if line[idx] == "" else line[idx]
result = result + int(curr_result) if op == '+' else result * int(curr_result)
idx += 1
return result

num_lines = content[:-1]
max_line_len = max([len(line) for line in num_lines])
raw_op_line = content[-1].strip()
op_line = []
for op_char in raw_op_line:
if op_char == '+':
op_line.append('+')
elif op_char == '*':
op_line.append('*')

idx, op_idx = 0, 0
num_buffer = ["" for _ in range(len(num_lines))]
result = 0

while idx < max_line_len :
is_all_space = True
for line in num_lines:
if line[idx] != ' ':
is_all_space = False
break

if is_all_space:
result += add_num_buffer(num_buffer, op_line[op_idx])
num_buffer = ["" for _ in range(len(num_lines))]
op_idx += 1
else:
for line_idx, line in enumerate(num_lines):
num_buffer[line_idx] += line[idx]
idx += 1
result += add_num_buffer(num_buffer, op_line[op_idx])
num_buffer = ["" for _ in range(len(num_lines))]
print(result)

这道题比较tricky一些,思路是这样的:

  1. 将数字行和运算符行分开,这里,不能用strip,否则会将一些行最后的空格也删掉。
  2. 用一个idx遍历每一个位置,如果它们全都是空格,就将num_buffer中的数字进行运算。
  3. 否则,就在num_buffer中加入读取到的字符。

7-1:向下行进的分歧次数

给了一张图,从上往下走,遇到一个^就分裂成左右两条路,计算分裂的次数。就是个模拟题。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
with open("7.input", "r") as f:
content = f.readlines()

graph = []
for line in content:
graph.append([])
for c in line.strip():
graph[-1].append(c if c != "S" else "1")

result = 0

for line_idx in range(len(graph[1:])):
for char_idx in range(len(graph[line_idx])):
if graph[line_idx-1][char_idx] == "1" and graph[line_idx][char_idx] == "^":
result += 1
if char_idx == 0 :
graph[line_idx][char_idx+1] = "1"
elif char_idx == len(graph[line_idx]) - 1:
graph[line_idx][char_idx-1] = "1"
else:
graph[line_idx][char_idx-1] = "1"
graph[line_idx][char_idx+1] = "1"
elif graph[line_idx-1][char_idx] == "1":
graph[line_idx][char_idx] = "1"

print(result)

7-2:向下行进的不同路径

现在,分裂的方向是不确定的,让我们算所有可能的路径。这个时候只需要在每次分裂的时候,记录到这个分裂点共有几条路即可。代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
with open("7.input", "r") as f:
content = f.readlines()

graph = []
for line in content:
graph.append([])
for c in line.strip():
if c == "S":
graph[-1].append([1])
elif c == ".":
graph[-1].append([0])
elif c == "^":
graph[-1].append([-1])
else:
raise NotImplementedError

barrier = -1
for line_idx in range(1, len(graph[1:])+1):
for elem_idx in range(len(graph[line_idx])):
upper_flow = graph[line_idx-1][elem_idx][0]
curr_terrain = graph[line_idx][elem_idx][0]
# Flow to barrier
if curr_terrain == barrier:
if elem_idx == 0:
graph[line_idx][elem_idx+1][0] += upper_flow
elif elem_idx == len(graph[line_idx]) - 1:
graph[line_idx][elem_idx-1][0] += upper_flow
else:
graph[line_idx][elem_idx-1][0] += upper_flow
graph[line_idx][elem_idx+1][0] += upper_flow
# Flow naturally
elif curr_terrain != barrier and upper_flow != barrier:
graph[line_idx][elem_idx][0] += upper_flow

result = 0
for lst in graph[-1]:
curr_result = lst[0]
result += curr_result if curr_result > barrier else 0
print(result)

8-1:最大三个子图的节点数之积

给定了一些三维坐标,每次连接距离最小的两个节点,最后求三个最大子图的节点数之积。图论是我最弱的一项算法领域了。说实话这道题我没什么好的想法,只有暴力+BFS。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import math

def calc_dist(x1, y1, z1, x2, y2, z2):
return math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2) + math.pow(z1 - z2, 2))

def bfs(graph: list[list[int]], start: int, visited: list[bool], visit_stack: list[int]) -> int:
max_hop = 1
node_queue = [start]

while len(node_queue) > 0:
curr_node = node_queue.pop(0)
for neighbor in graph[curr_node]:
if visited[neighbor]:
continue
visited[neighbor] = True
visit_stack.append(neighbor)
node_queue.append(neighbor)
max_hop = max(max_hop, len(visit_stack))
return max_hop

distance_list = []
connect_limit = 1000

with open("8.input", "r") as f:
content = f.readlines()

coordinate_list = []
for line in content:
coordinate_list.append([int(x) for x in line.strip().split(",")])

for i in range(len(coordinate_list)):
for j in range(i + 1, len(coordinate_list)):
distance = calc_dist(coordinate_list[i][0], coordinate_list[i][1], coordinate_list[i][2], coordinate_list[j][0], coordinate_list[j][1], coordinate_list[j][2])
distance_list.append([[i, j], distance])

distance_list.sort(key=lambda x: x[1])


graph = [[] for i in range(len(coordinate_list))]

for i in range(connect_limit):
connect_from, connect_to = distance_list[i][0]
graph[connect_from].append(connect_to)
graph[connect_to].append(connect_from)

visited = [False for i in range(len(coordinate_list))]
hop_list = []
for i in range(len(coordinate_list)):
if visited[i]:
continue
visited[i] = True
visit_stack = [i]
max_hop, curr_hop = 1, 1
hop_list.append(bfs(graph, i, visited, visit_stack) if graph[i] != [] else 1)

hop_list.sort()
print(hop_list)
result = 1
result = result * hop_list[-1] * hop_list[-2] * hop_list[-3]
print(result)

8-2:何时为连通图

这道题依旧是按照上一道题的连接方法,只不过这次,让我们计算连接成一张图时候,最后连接的两个x坐标之积。连通图最少有n-1条边,非连通图的边少于n-1条,故代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import math

with open("8.input", "r") as f:
content = f.readlines()

def calc_dist(x1, y1, z1, x2, y2, z2):
return math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2) + math.pow(z1 - z2, 2))

def get_visit_node_num(l):
result = 0
for i in l:
if not node_visited[i]:
result += 1
return result

coordinate_list = []
distance_list = []

for line in content:
coordinate_list.append([int(x) for x in line.strip().split(",")])

for i in range(len(coordinate_list)):
for j in range(i + 1, len(coordinate_list)):
distance = calc_dist(coordinate_list[i][0], coordinate_list[i][1], coordinate_list[i][2], coordinate_list[j][0], coordinate_list[j][1], coordinate_list[j][2])
distance_list.append([[i, j], distance])

distance_list.sort(key=lambda x: x[1])

node_visited = [False for i in range(len(coordinate_list))]
node_num, connect_num = 0, 0
for distance_elem in distance_list:
connect_from, connect_to = distance_elem[0]
if not node_visited[connect_from] and not node_visited[connect_to]:
node_visited[connect_from] = True
node_visited[connect_to] = True
node_num += 2
connect_num += 1
elif not node_visited[connect_from] and node_visited[connect_to]:
node_visited[connect_from] = True
node_num += 1
connect_num += 1
elif node_visited[connect_from] and not node_visited[connect_to]:
node_visited[connect_to] = True
node_num += 1
connect_num += 1
else:
connect_num += 1

if connect_num >= len(coordinate_list) - 1 and node_num == len(coordinate_list):
print(coordinate_list[connect_from][0] * coordinate_list[connect_to][0])
break

9-1:最大的方块

给定一些二维坐标,求这些坐标点之间能形成的最大方块的面积,暴力:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
with open("9.input", "r") as f:
content = f.readlines()

def calc_area(x1, y1, x2, y2):
return (x2 - x1 + 1) * (y2 - y1 + 1)


coordinate_list = []
for line in content:
coordinate_list.append([int(x) for x in line.strip().split(",")])

max_area = 0
for i in range(len(coordinate_list)):
for j in range(i + 1, len(coordinate_list)):
x1, y1 = coordinate_list[i][0], coordinate_list[i][1]
x2, y2 = coordinate_list[j][0], coordinate_list[j][1]
max_area = max(max_area, calc_area(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2)))

print(max_area)

文章作者:
文章链接: https://www.coderlock.site/2025/12/28/【Python】Advent-Of-Code-2025代码实录/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 寒夜雨