|
8 | 8 | print("- Continue until you reach 1") |
9 | 9 | print("=" * 50) |
10 | 10 |
|
| 11 | +MAX_STEPS = 100000 |
| 12 | +MAX_VALUE = 10**18 |
| 13 | +MAX_INPUT = 10**12 |
| 14 | +steps_cache = {1: 0} |
| 15 | + |
| 16 | +def collatz_next(n): |
| 17 | + return n // 2 if n % 2 == 0 else 3 * n + 1 |
| 18 | + |
| 19 | +def get_remaining_sequence(n): |
| 20 | + seq = [] |
| 21 | + while n != 1: |
| 22 | + n = collatz_next(n) |
| 23 | + seq.append(n) |
| 24 | + return seq |
| 25 | +def collatz_sequence(start): |
| 26 | + if start in steps_cache: |
| 27 | + n = start |
| 28 | + yield n |
| 29 | + while n != 1: |
| 30 | + n = collatz_next(n) |
| 31 | + yield n |
| 32 | + return |
| 33 | + |
| 34 | + n = start |
| 35 | + path = [n] |
| 36 | + steps = 0 |
| 37 | + |
| 38 | + yield n |
| 39 | + |
| 40 | + while n != 1 and steps < MAX_STEPS: |
| 41 | + n = collatz_next(n) |
| 42 | + steps += 1 |
| 43 | + |
| 44 | + if n > MAX_VALUE: |
| 45 | + print("\n\n⚠ Computation stopped: safety limit reached") |
| 46 | + break |
| 47 | + |
| 48 | + yield n |
| 49 | + path.append(n) |
| 50 | + |
| 51 | + if n in steps_cache: |
| 52 | + for remaining in get_remaining_sequence(n): |
| 53 | + yield remaining |
| 54 | + steps += steps_cache[n] |
| 55 | + break |
| 56 | + |
| 57 | + total = steps_cache.get(n, 0) |
| 58 | + for value in reversed(path): |
| 59 | + total += 1 |
| 60 | + steps_cache[value] = total |
| 61 | + |
11 | 62 | while True: |
12 | 63 | try: |
13 | 64 | number = int(input("\nEnter a positive integer to start: ")) |
14 | 65 | if number > 0: |
| 66 | + if number > MAX_INPUT: |
| 67 | + print(f"Input too large! Maximum allowed: {MAX_INPUT:,}") |
| 68 | + continue |
15 | 69 | break |
16 | 70 | else: |
17 | 71 | print("Please enter a positive integer!") |
18 | 72 | except ValueError: |
19 | 73 | print("Please enter a valid number!") |
20 | 74 |
|
21 | 75 | original_number = number |
22 | | -sequence = [number] |
23 | | -steps = 0 |
24 | 76 |
|
25 | 77 | print(f"\nStarting with: {number}") |
26 | 78 | print("\nSequence:") |
27 | | -print(number, end="") |
28 | | - |
29 | | -while number != 1: |
30 | | - if number % 2 == 0: |
31 | | - number = number // 2 |
32 | | - else: |
33 | | - number = 3 * number + 1 |
34 | | - |
35 | | - sequence.append(number) |
| 79 | + |
| 80 | +sequence = [] |
| 81 | +steps = 0 |
| 82 | +max_value = number |
| 83 | + |
| 84 | +gen = collatz_sequence(number) |
| 85 | + |
| 86 | +first = next(gen) |
| 87 | +print(first, end="") |
| 88 | +sequence.append(first) |
| 89 | + |
| 90 | +for num in gen: |
| 91 | + sequence.append(num) |
36 | 92 | steps += 1 |
37 | | - |
38 | | - print(f" → {number}", end="") |
39 | | - |
| 93 | + max_value = max(max_value, num) |
| 94 | + print(f" → {num}", end="") |
40 | 95 | if steps % 10 == 0: |
41 | 96 | print() |
42 | 97 |
|
|
46 | 101 | print(f"Starting number: {original_number}") |
47 | 102 | print(f"Total steps: {steps}") |
48 | 103 | print(f"Sequence length: {len(sequence)}") |
49 | | -print(f"Highest number reached: {max(sequence)}") |
| 104 | +print(f"Highest number reached: {max_value}") |
50 | 105 |
|
51 | 106 | if len(sequence) <= 100: |
52 | 107 | view_details = input("\nWould you like to see step-by-step details? (yes/no): ").lower() |
|
0 commit comments