-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcollatz.py
123 lines (95 loc) · 2.89 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
import matplotlib.pyplot as plt
from collections import Counter
MAX_I = 200
becomes_even = 0
becomes_odd = 0
# for i in range(1, MAX_I, 2):
# result = (i * 3 + 1) / 2
# if result % 2 == 0:
# becomes_even += 1
# else:
# becomes_odd += 1
# for i in range(0, MAX_I, 2):
# if (i / 2) % 2 == 0:
# becomes_even += 1
# else:
# becomes_odd += 1
def get_full_pattern(n, combine=True, stop_on_dip=False):
seen = set()
pattern = ""
initial = n
while True:
seen.add(n)
if n % 2 == 0:
pattern += "X"
n = n / 2
else:
pattern += "O"
if combine:
n = (n * 3 + 1) / 2
else:
n = n * 3 + 1
if n in seen or stop_on_dip and n < initial:
break
return pattern
def get_collatz_pattern(n, depth, combine=True):
pattern = ""
for _ in range(depth):
if n % 2 == 0:
pattern += "X"
n = n / 2
else:
pattern += "O"
if combine:
n = (n * 3 + 1) / 2
else:
n = n * 3 + 1
return pattern
def checker():
BLOCKS_TO_CHECK = 1
DEPTH = 8
for DEPTH in range(1, 15):
BLOCK_LENGTH = 2**DEPTH
patterns = []
for i in range(BLOCK_LENGTH * BLOCKS_TO_CHECK):
pattern = get_collatz_pattern(i, DEPTH)
full_pattern = get_full_pattern(i)
# print(f"{i}\t{pattern}\t{full_pattern}")
patterns.append(pattern)
first_block = patterns[:BLOCK_LENGTH]
depth_pattern = ""
for pattern in first_block:
depth_pattern += pattern[DEPTH - 1]
print(DEPTH, Counter(depth_pattern))
# print(f"{first_block} repeats infinitely")
assert patterns == first_block * BLOCKS_TO_CHECK
def get_full_map(width, height, **kwargs):
collatz_map = []
for y in range(height):
row = [
1 if symbol == "O" else 0
for symbol in get_collatz_pattern(y, width, **kwargs)
]
collatz_map.append(row)
# return list(zip(*collatz_map))
return collatz_map
def get_actual_map(width, height, **kwargs):
collatz_map = []
for y in range(height):
row = [
[0, 255, 0, 255] if symbol == "O" else [255, 0, 0, 255]
for symbol in get_full_pattern(y, **kwargs)
][:width]
if len(row) < width:
row += [[0, 0, 0, 0]] * (width - len(row))
collatz_map.append(row)
return collatz_map
# actual_map = get_actual_map(200, 2056)
# shortcut_map = get_full_map(100, 128, combine=False)
actual_optimized_map = get_actual_map(200, 2056, stop_on_dip=False)
full_map = get_full_map(200, 2056)
fig, (ax2, ax3) = plt.subplots(1, 2, sharex=True, sharey=True)
# ax1.imshow(actual_map)
ax2.imshow(actual_optimized_map)
ax3.imshow(full_map)
plt.show()