Symbol(clack:cancel)

This commit is contained in:
2025-12-26 17:35:14 +08:00
parent 266544ac47
commit 25469e1022
54 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
"""
The following iterative sequence is defined for the set of positive integers:
n -> n/2 (is even)
n -> 3n + 1 (is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
It can be seen that this sequence (starting at 13 and finishing at 1 ) contains 10 terms.
Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
"""
import time
from functools import cache
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} took {end_time - start_time:.6f} seconds")
return result
return wrapper
def is_even(n: int) -> bool:
return n & 1 == 0
def collatz_sequence(n: int) -> list[int]:
sequence = [n]
while sequence[-1] != 1:
if is_even(n):
n = n // 2
else:
n = 3 * n + 1
sequence.append(n)
return sequence
def longest_collatz_sequence(limit: int) -> int:
longest_length = 0
longest_start = 0
for i in range(1, limit + 1):
length = len(collatz_sequence(i))
if length > longest_length:
longest_length = length
longest_start = i
return longest_start
@cache
def chain_length(n):
if n == 1:
return 0
next_term = 3 * n + 1 if n % 2 else n // 2
return chain_length(next_term) + 1
@timer
def main_do() -> None:
print(longest_collatz_sequence(1000000))
@timer
def main_cache() -> None:
print(max(range(1, 1000001), key=chain_length))
if __name__ == "__main__":
main_do()
main_cache()

View File

@@ -0,0 +1,3 @@
暴力试算,虽然总能解决问题,但是要损耗时间。有的时候没什么好想法的时候,的确可以用来作为解法。
但是从hash列表的角度来说已经计算过的数值可以用来避免重复计算提高效率。
这一点还是很值得记录的。