Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- # Filename: ulam_py2y41_v1.py
- # Version: 1.0.1
- # Author: Jeoi Reqi
- """
- Ulam Spiral Visualizer Of Primes & Palindromic Primes On The Golden Line:
- This Python script generates a spiral visualization of primes and palindromic primes.
- The Ulam Spiral is a spiral arrangement of natural numbers, where the numbers are plotted on a grid & primes are highlighted.
- In this script, the golden line is traced by the equation [P = y^2 - y + 41], where 'y' is the starting value determined by the user.
- The golden line represents a diagonal line crossing the center where 'y' is.
- Primes (indicated by red dots) & Palindromic Primes (indicated by blue dots) are distinctly marked, with some Primes being Palindromic Primes.
- Requirements:
- - Python 3
- - Matplotlib
- Usage:
- - Run the script in a terminal or command prompt.
- - Enter the starting value for 'y', which determines the plot's central starting point value.
- - Enter the number of iterations of 'y' to be visualized in the spiral grid.
- - The script will generate a plot and save it as a PNG file (e.g., 'y41_i100.png').
- - The terminal output will be saved in a dynamically named text file (e.g., 'output_y41_i100.txt').
- Note:
- - The golden line is traced by the equation [P = y^2 - y + 41].
- - Close the plot window to terminate the script.
- Equation: P=y^2-y+41
- Definition:
- Must be TRUE:
- [P] is a Prime
- [P] is possibly a Palindrome
- [y] is a natural whole integer
- [y] is a positive number
- !! [y] is not less than 2 (y>2)
- (Note: P = Prime Pattern Breaks if y>2)
- Example: (if y = 4) Find P:
- [P = y^2-y+41]
- 4^2-4+41 = P
- 4x4-4+37 = P
- 16-4 +37 = P
- 12 + 37 = 49
- Prime Value is equal to (4 squared minus 4 plus 41)
- P = 49 (Prime)
- """
- # Imports
- import matplotlib.pyplot as plt
- import time
- import sys
- import os
- # Create an empty list to capture terminal output
- terminal_output = []
- plt.style.use('dark_background')
- plt.ion()
- # checks if a given number is prime or not
- def is_prime(num):
- if num < 2:
- return False
- for i in range(2, int(num**0.5) + 1):
- if num % i == 0:
- return False
- return True
- # change the x/y coordinates based on the state
- def march(state, x, y):
- if state == 0:
- x += 1
- if state == 1:
- y += 1
- if state == 2:
- x -= 1
- if state == 3:
- y -= 1
- return x, y
- # Create a list to capture the terminal output
- terminal_output = []
- # Ask the user for the starting number
- y_value = int(input("Enter the starting number (y): "))
- while y_value < 2:
- # If the user enters a starting number less than 2, prompt them to enter a valid one
- print("Please enter a starting number greater than or equal to 2.")
- y_value = int(input("Enter the starting number (y): "))
- # Ask the user for the number of iterations
- iterations_number = int(input("Enter the number of iterations (i): "))
- # Initialize variables for the previous coordinates
- l_x = 1
- l_y = 0
- # Initialize current coordinates based on user input
- x = 0
- y = y_value # Use the user's input as the starting number
- # Initialize variables for the Ulam Spiral algorithm
- state = -1
- factor = -1
- steps = 1
- current_steps = 0
- # Record the start time for performance measurement
- start_time = time.time()
- # Create a list to store plot data
- plot_data = []
- # Create a dynamic filename for the plot
- plot_filename = f"y{y_value}_i{iterations_number}.png"
- # Create a single plot
- fig, ax = plt.subplots()
- # Loop through the range of iterations to generate points for the Ulam Spiral
- for i in range(y_value, y_value + iterations_number):
- # Store the current coordinates as the previous coordinates
- l_x = x
- l_y = y
- # Increment the steps taken in the current direction
- current_steps += 1
- # Check if the current steps have reached the predefined number of steps
- if current_steps >= steps:
- # Increase the factor to change the direction of movement
- factor += 1
- current_steps = 0
- # Move to the next coordinates based on the Ulam Spiral algorithm
- x, y = march(state, x, y)
- # Increase the state to change the direction of movement
- state += 1
- # Reset the state to 0 if it exceeds 3 (four directions in total)
- if state > 3:
- state = 0
- # Change the factor after every two steps
- if factor == 2:
- factor = 0
- steps += 1
- # If the current steps are not 0, move to the next coordinates
- if current_steps != 0:
- x, y = march(state, x, y)
- # Define the two points to be plotted
- point1 = [x, y]
- point2 = [l_x, l_y]
- # Define the x and y values for plotting
- x_values = [point1[0], point2[0]]
- y_values = [point1[1], point2[1]]
- # Plot the line connecting the two points with a yellow color and reduced opacity
- ax.plot(x_values, y_values, 'y-', alpha=0.25)
- # Check if the current number in the iteration is a prime number
- if is_prime(i):
- # Check if the prime number is also a palindromic prime with at least two digits
- if str(i) == str(i)[::-1] and len(str(i)) >= 2:
- # Plot the point in blue if it is a palindromic prime
- ax.plot(x, y, 'bo')
- # Annotate the point with the palindromic prime number
- ax.annotate(i, (x, y), color='white', fontsize=8, ha='center', va='center')
- else:
- # Plot the point in red if it is a prime but not a palindromic prime
- ax.plot(x, y, 'ro')
- # Append the current iteration data to the plot_data list
- plot_data.append((i, x, y))
- # Set the dynamic title for the plot
- ax.set_title(f"y{y_value}_i{iterations_number}")
- # Remove ticks from the plot
- ax.set_xticks([])
- ax.set_yticks([])
- #plt.pause(0.001) # Pause for a short duration to allow plotting if needed
- # Allow user early termination: Check if any figures are open, break the loop if not
- if not plt.get_fignums():
- print("Plotting terminated by user.")
- break
- # Automatically save the image with a dynamic filename
- plt.savefig(plot_filename)
- # Close the figure to prevent issues with plt.show()
- plt.close()
- end_time = time.time()
- elapsed_time = end_time - start_time
- # Save the terminal output to a text file with a dynamic filename
- output_filename = f"output_{plot_filename.replace('.png', '.txt')}"
- with open(output_filename, "w") as file:
- # Write the starting value for 'y' and the number of iterations to the file
- file.write(f"value for y: {y_value}\n")
- file.write(f"Enter the number of iterations: {iterations_number}\n")
- file.write("\nResults:\n")
- # Iterate through the plot data to generate output for each iteration
- for data in plot_data:
- y_value, x_value, _ = data
- P = x_value**2 - x_value + y_value
- # Check if the calculated value (P) is a prime number
- if is_prime(P):
- # Check if the prime number is also a palindromic prime
- if is_prime(P) and str(P) == str(P)[::-1]:
- # Write the output for palindromic primes
- result_str = f"[y={y_value}, P={P}] -- [PALINDROMIC PRIME]"
- else:
- # Write the output for non-palindromic primes
- result_str = f"[y={y_value}, P={P}]"
- # Write the result string to the file
- file.write(result_str + "\n")
- # Terminal Output Messages
- print(f"\nPlot data saved to 'plot_data.txt'\n")
- print(f"\nTerminal output saved to {output_filename}\n")
- # Print the elapsed time in hours, minutes, and seconds format
- hours, remainder = divmod(elapsed_time, 3600)
- minutes, seconds = divmod(remainder, 60)
- print(f"\nTime elapsed: {int(hours)} hours, {int(minutes)} minutes, {seconds:.2f} seconds\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement