-
Notifications
You must be signed in to change notification settings - Fork 0
/
collatz.py
141 lines (120 loc) · 4.3 KB
/
collatz.py
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import sqlite3
import datetime
import signal
import sys
from statistics import median, pstdev
DB_FILE = 'collatz.db'
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
# Define the database structure.
def setup_database():
"""
Create the required tables in the database.
"""
tables = {
"collatz": """CREATE TABLE IF NOT EXISTS collatz (
starting_number INTEGER,
number_of_steps INTEGER,
max_value INTEGER,
sequence_length INTEGER,
convergence INTEGER,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)""",
"distribution": """CREATE TABLE IF NOT EXISTS distribution (
stat_name TEXT,
value REAL
)""",
"sequence_length": """CREATE TABLE IF NOT EXISTS sequence_length (
number INTEGER PRIMARY KEY,
steps INTEGER
)""",
"convergence": """CREATE TABLE IF NOT EXISTS convergence (
number INTEGER PRIMARY KEY,
converges INTEGER
)""",
"date_time": """CREATE TABLE IF NOT EXISTS date_time (
id INTEGER PRIMARY KEY,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)""",
}
for table in tables.values():
c.execute(table)
# Check the Collatz conjecture for the given number.
def check_collatz(n):
"""
Perform the Collatz conjecture for a number n.
"""
original_n, steps, max_value = n, 0, n
sequence = []
while True:
sequence.append(n)
c.execute('SELECT steps FROM sequence_length WHERE number = ?', (n,))
row = c.fetchone()
if row:
steps += row[0]
break
elif n % 2 == 0:
n //= 2
else:
n = 3 * n + 1
steps += 1
max_value = max(max_value, n)
if n in {1, 2, 4}:
break
for i, num in enumerate(sequence):
c.execute('INSERT OR REPLACE INTO sequence_length VALUES (?, ?)', (num, steps - i))
converges = 1 if n == 1 else 0
c.execute('INSERT OR REPLACE INTO convergence VALUES (?, ?)', (original_n, converges))
return steps, max_value, steps - 1, converges
# Calculate statistics after the script is stopped.
def calculate_stats():
"""
Calculate basic statistical values for max_values.
"""
c.execute('SELECT max_value FROM collatz')
max_values = [row[0] for row in c.fetchall()]
stats = {
'min': min(max_values) if max_values else 0,
'max': max(max_values) if max_values else 0,
'mean': sum(max_values) / len(max_values) if max_values else 0,
'median': median(max_values) if max_values else 0,
'std_dev': pstdev(max_values) if max_values else 0
}
for stat, value in stats.items():
c.execute('INSERT INTO distribution VALUES (?, ?)', (stat, value))
# Define shutdown operations.
def shutdown(signal, frame):
"""
Perform operations needed before shutdown.
"""
calculate_stats()
conn.close()
sys.exit(0)
# The main function.
def main():
"""
Main function to process each number for the Collatz conjecture.
"""
setup_database()
c.execute('SELECT MAX(starting_number) FROM collatz')
last_number = c.fetchone()[0]
start_number = last_number + 1 if last_number else 1
signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)
for i in range(start_number, float('inf')):
print(f"Processing: {i}")
try:
steps, max_value, sequence_length, converges = check_collatz(i)
except Exception as e:
print(f"Error encountered while processing {i}: {e}")
break
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
c.execute("INSERT INTO collatz VALUES (?, ?, ?, ?, ?, ?)", (i, steps, max_value, sequence_length, converges, timestamp))
c.execute("INSERT INTO date_time (id) VALUES (?)", (i,))
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"An error occurred: {e}")
finally:
conn.close()