Skip to content

Commit 5a32966

Browse files
committed
fix(collatz): correct step cache corruption in Collatz Conjecture
The memoization cache (steps_cache) was corrupting values due to including the terminal element (n=1 or a cached value) in the cache-update loop. This caused double-counting and incorrect step counts on successive runs. Fix: use path[:-1] in the cache update loop to exclude the last path element, which is either 1 (already at cache[1]=0) or a previously cached value. This keeps cache entries correct. Fixes: steam-bell-92#835
1 parent ecb99c8 commit 5a32966

1 file changed

Lines changed: 69 additions & 18 deletions

File tree

math/Collatz-Conjecture/Collatz-Conjecture.py

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,60 @@
66
print(" - Continue until you reach 1\n")
77

88
MAX_STEPS = 100000
9+
MAX_VALUE = 10**18
910
MAX_INPUT = 10**12
11+
steps_cache = {1: 0}
12+
13+
14+
def collatz_next(n):
15+
return n // 2 if n % 2 == 0 else 3 * n + 1
16+
17+
18+
def get_remaining_sequence(n):
19+
seq = []
20+
while n != 1:
21+
n = collatz_next(n)
22+
seq.append(n)
23+
return seq
24+
25+
26+
def collatz_sequence(start):
27+
if start in steps_cache:
28+
n = start
29+
yield n
30+
while n != 1:
31+
n = collatz_next(n)
32+
yield n
33+
return
34+
35+
n = start
36+
path = [n]
37+
steps = 0
38+
39+
yield n
40+
41+
while n != 1 and steps < MAX_STEPS:
42+
n = collatz_next(n)
43+
steps += 1
44+
45+
if n > MAX_VALUE:
46+
print("\n\n⚠ Computation stopped: safety limit reached")
47+
break
48+
49+
yield n
50+
path.append(n)
51+
52+
if n in steps_cache:
53+
for remaining in get_remaining_sequence(n):
54+
yield remaining
55+
steps += steps_cache[n]
56+
break
57+
58+
total = steps_cache.get(n, 0)
59+
for value in reversed(path[:-1]):
60+
total += 1
61+
steps_cache[value] = total
62+
1063

1164
while True:
1265
try:
@@ -22,27 +75,25 @@
2275
continue
2376

2477
original_number = number
25-
sequence = [number]
26-
steps = 0
27-
max_value = number
2878

2979
print(f"\n🚀 Starting with: {number}")
3080
print("📊 Sequence:")
31-
print(number, end="")
32-
33-
while number != 1 and steps < MAX_STEPS:
34-
if number % 2 == 0:
35-
number = number // 2
36-
else:
37-
number = 3 * number + 1
38-
81+
82+
sequence = []
83+
steps = 0
84+
max_value = number
85+
86+
gen = collatz_sequence(number)
87+
88+
first = next(gen)
89+
print(first, end="")
90+
sequence.append(first)
91+
92+
for num in gen:
93+
sequence.append(num)
3994
steps += 1
40-
sequence.append(number)
41-
42-
if number > max_value:
43-
max_value = number
44-
45-
print(f" ➡️ {number}", end="")
95+
max_value = max(max_value, num)
96+
print(f" ➡️ {num}", end="")
4697
if steps % 10 == 0:
4798
print()
4899

@@ -65,7 +116,7 @@
65116
print(f" Step {i + 1}: {current} is odd ➡️ ({current} × 3) + 1 = {next_num}")
66117

67118
print("\n🎉 The sequence reached 1 as expected!")
68-
119+
69120
again = input("\n🔄 Do you want to test another number? (y/n): ").strip().lower()
70121
if again != 'y':
71122
print("\n👋 Thanks for exploring the Collatz Conjecture! Goodbye!\n")

0 commit comments

Comments
 (0)