arnel8888's picture
Uploaded codebase
629d1ff verified
Raw
History Blame Contribute Delete
2.84 kB
# This module contains functions to generate and visualize the Collatz sequence.
# Importing necessary libraries
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colormaps
import tempfile
# Generate the Collatz sequence for a given n
def get_sequence(n):
sequence = [n]
curr = n
while curr != 1:
if curr % 2 == 0:
curr = curr // 2
else:
curr = 3 * curr + 1
sequence.append(curr)
sequence.reverse()
return sequence
# Draw all branches as a static plot and return the image file path
def plot_collatz_sequence(max_number, slant_angle, fan_angle, colormap, colorperiod):
# Get all sequences
branches = [get_sequence(i) for i in range(1, max_number + 1)]
num_branches = len(branches)
# Convert angles to radians
slant_angle = np.radians(slant_angle)
fan_angle = np.radians(fan_angle)
# Set up figure
fig, ax = plt.subplots(figsize = (8, 10))
ax.set_aspect('equal')
ax.axis('off')
# Set line length and canvas limits
line_length = 1.5
max_steps = max(len(branch) for branch in branches)
x_margin = max_steps * line_length / 4
y_margin = max_steps * line_length / 2
ax.set_xlim(-x_margin, x_margin)
ax.set_ylim(0, y_margin)
# Slant angles for normal branching
slant_angles = np.linspace(-slant_angle, slant_angle, num_branches)
# Fan-out angle for first segment
fan_angles = np.linspace(-fan_angle, fan_angle, num_branches)
# Prepare colors from colormap
num_colors = num_branches // colorperiod
remainder = num_branches % colorperiod
base_cmap = colormaps[colormap].resampled(num_colors)
base_colors = [base_cmap(i) for i in range(num_colors)]
colors = base_colors * colorperiod
if remainder > 0:
colors += [base_cmap(i) for i in range(remainder)]
# Draw all branches
for i, branch in enumerate(branches):
x, y = 0, 0
positions = [(x, y)]
for j in range(len(branch) - 1):
next_val = branch[j + 1]
if j == 0:
angle = np.pi / 2 + fan_angles[i]
else:
angle = np.pi / 2 + slant_angles[i] if next_val % 2 == 0 else np.pi / 2 - slant_angles[i]
dx = line_length * np.cos(angle)
dy = line_length * np.sin(angle)
x, y = x + dx, y + dy
positions.append((x, y))
xs, ys = zip(*positions)
ax.plot(xs, ys, color = colors[i], linewidth = 2)
# Save to temp file
with tempfile.NamedTemporaryFile(delete = False, suffix = ".png") as tmpfile:
plt.savefig(tmpfile.name, bbox_inches = 'tight', dpi = 100)
plt.close(fig)
return tmpfile.name