Advertisement
Python253

ulam_py2y41_v1

Mar 10th, 2024 (edited)
633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.07 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Filename: ulam_py2y41_v1.py
  4. # Version: 1.0.1
  5. # Author: Jeoi Reqi
  6.  
  7. """
  8. Ulam Spiral Visualizer Of Primes & Palindromic Primes On The Golden Line:
  9.  
  10. This Python script generates a spiral visualization of primes and palindromic primes.
  11. The Ulam Spiral is a spiral arrangement of natural numbers, where the numbers are plotted on a grid & primes are highlighted.
  12. 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.
  13. The golden line represents a diagonal line crossing the center where 'y' is.
  14. Primes (indicated by red dots) & Palindromic Primes (indicated by blue dots) are distinctly marked, with some Primes being Palindromic Primes.
  15.  
  16. Requirements:
  17. - Python 3
  18. - Matplotlib
  19.  
  20. Usage:
  21. - Run the script in a terminal or command prompt.
  22. - Enter the starting value for 'y', which determines the plot's central starting point value.
  23. - Enter the number of iterations of 'y' to be visualized in the spiral grid.
  24. - The script will generate a plot and save it as a PNG file (e.g., 'y41_i100.png').
  25. - The terminal output will be saved in a dynamically named text file (e.g., 'output_y41_i100.txt').
  26.  
  27. Note:
  28. - The golden line is traced by the equation [P = y^2 - y + 41].
  29. - Close the plot window to terminate the script.
  30.  
  31. Equation:   P=y^2-y+41
  32.  
  33. Definition:
  34.        Must be TRUE:
  35.            [P] is a Prime
  36.            [P] is possibly a Palindrome
  37.            [y] is a natural whole integer
  38.            [y] is a positive number
  39.      !!    [y] is not less than 2  (y>2)        
  40.        (Note: P = Prime Pattern Breaks if y>2)
  41.        
  42.        
  43.        Example: (if y = 4) Find P:
  44.            
  45.            [P = y^2-y+41]
  46.  
  47.            4^2-4+41 = P
  48.            4x4-4+37 = P
  49.            16-4 +37 = P
  50.            12 + 37 = 49
  51.  
  52.            Prime Value is equal to (4 squared minus 4 plus 41)
  53.            P = 49 (Prime)
  54. """
  55.  
  56. # Imports
  57. import matplotlib.pyplot as plt
  58. import time
  59. import sys
  60. import os
  61.  
  62. # Create an empty list to capture terminal output
  63. terminal_output = []
  64.  
  65. plt.style.use('dark_background')
  66. plt.ion()
  67.  
  68. # checks if a given number is prime or not
  69. def is_prime(num):
  70.     if num < 2:
  71.         return False
  72.     for i in range(2, int(num**0.5) + 1):
  73.         if num % i == 0:
  74.             return False
  75.     return True
  76.  
  77. # change the x/y coordinates based on the state
  78. def march(state, x, y):
  79.     if state == 0:
  80.         x += 1
  81.     if state == 1:
  82.         y += 1
  83.     if state == 2:
  84.         x -= 1
  85.     if state == 3:
  86.         y -= 1
  87.  
  88.     return x, y
  89.  
  90. # Create a list to capture the terminal output
  91. terminal_output = []
  92.  
  93. # Ask the user for the starting number
  94. y_value = int(input("Enter the starting number (y): "))
  95.  
  96. while y_value < 2:
  97.     # If the user enters a starting number less than 2, prompt them to enter a valid one
  98.     print("Please enter a starting number greater than or equal to 2.")
  99.     y_value = int(input("Enter the starting number (y): "))
  100.  
  101. # Ask the user for the number of iterations
  102. iterations_number = int(input("Enter the number of iterations (i): "))
  103.  
  104. # Initialize variables for the previous coordinates
  105. l_x = 1
  106. l_y = 0
  107.  
  108. # Initialize current coordinates based on user input
  109. x = 0
  110. y = y_value  # Use the user's input as the starting number
  111.  
  112. # Initialize variables for the Ulam Spiral algorithm
  113. state = -1
  114. factor = -1
  115. steps = 1
  116. current_steps = 0
  117.  
  118. # Record the start time for performance measurement
  119. start_time = time.time()
  120.  
  121. # Create a list to store plot data
  122. plot_data = []
  123.  
  124. # Create a dynamic filename for the plot
  125. plot_filename = f"y{y_value}_i{iterations_number}.png"
  126.  
  127. # Create a single plot
  128. fig, ax = plt.subplots()
  129.  
  130. # Loop through the range of iterations to generate points for the Ulam Spiral
  131. for i in range(y_value, y_value + iterations_number):
  132.     # Store the current coordinates as the previous coordinates
  133.     l_x = x
  134.     l_y = y
  135.  
  136.     # Increment the steps taken in the current direction
  137.     current_steps += 1
  138.  
  139.     # Check if the current steps have reached the predefined number of steps
  140.     if current_steps >= steps:
  141.         # Increase the factor to change the direction of movement
  142.         factor += 1
  143.         current_steps = 0
  144.  
  145.         # Move to the next coordinates based on the Ulam Spiral algorithm
  146.         x, y = march(state, x, y)
  147.  
  148.         # Increase the state to change the direction of movement
  149.         state += 1
  150.  
  151.         # Reset the state to 0 if it exceeds 3 (four directions in total)
  152.         if state > 3:
  153.             state = 0
  154.  
  155.         # Change the factor after every two steps
  156.         if factor == 2:
  157.             factor = 0
  158.             steps += 1
  159.  
  160.     # If the current steps are not 0, move to the next coordinates
  161.     if current_steps != 0:
  162.         x, y = march(state, x, y)
  163.  
  164.     # Define the two points to be plotted
  165.     point1 = [x, y]
  166.     point2 = [l_x, l_y]
  167.  
  168.     # Define the x and y values for plotting
  169.     x_values = [point1[0], point2[0]]
  170.     y_values = [point1[1], point2[1]]
  171.  
  172.     # Plot the line connecting the two points with a yellow color and reduced opacity
  173.     ax.plot(x_values, y_values, 'y-', alpha=0.25)
  174.  
  175.     # Check if the current number in the iteration is a prime number
  176.     if is_prime(i):
  177.         # Check if the prime number is also a palindromic prime with at least two digits
  178.         if str(i) == str(i)[::-1] and len(str(i)) >= 2:
  179.             # Plot the point in blue if it is a palindromic prime
  180.             ax.plot(x, y, 'bo')
  181.            
  182.             # Annotate the point with the palindromic prime number
  183.             ax.annotate(i, (x, y), color='white', fontsize=8, ha='center', va='center')
  184.         else:
  185.             # Plot the point in red if it is a prime but not a palindromic prime
  186.             ax.plot(x, y, 'ro')
  187.  
  188.     # Append the current iteration data to the plot_data list
  189.     plot_data.append((i, x, y))
  190.  
  191.  
  192.     # Set the dynamic title for the plot
  193.     ax.set_title(f"y{y_value}_i{iterations_number}")
  194.  
  195.     # Remove ticks from the plot
  196.     ax.set_xticks([])
  197.     ax.set_yticks([])
  198.  
  199.     #plt.pause(0.001)  # Pause for a short duration to allow plotting if needed
  200.  
  201.     # Allow user early termination: Check if any figures are open, break the loop if not
  202.     if not plt.get_fignums():
  203.         print("Plotting terminated by user.")
  204.         break
  205.  
  206. # Automatically save the image with a dynamic filename
  207. plt.savefig(plot_filename)
  208.  
  209. # Close the figure to prevent issues with plt.show()
  210. plt.close()
  211.  
  212. end_time = time.time()
  213. elapsed_time = end_time - start_time
  214.        
  215. # Save the terminal output to a text file with a dynamic filename
  216. output_filename = f"output_{plot_filename.replace('.png', '.txt')}"
  217. with open(output_filename, "w") as file:
  218.     # Write the starting value for 'y' and the number of iterations to the file
  219.     file.write(f"value for y: {y_value}\n")
  220.     file.write(f"Enter the number of iterations: {iterations_number}\n")
  221.     file.write("\nResults:\n")
  222.    
  223.     # Iterate through the plot data to generate output for each iteration
  224.     for data in plot_data:
  225.         y_value, x_value, _ = data
  226.         P = x_value**2 - x_value + y_value
  227.  
  228.         # Check if the calculated value (P) is a prime number
  229.         if is_prime(P):
  230.             # Check if the prime number is also a palindromic prime
  231.             if is_prime(P) and str(P) == str(P)[::-1]:
  232.                 # Write the output for palindromic primes
  233.                 result_str = f"[y={y_value}, P={P}]   --   [PALINDROMIC PRIME]"
  234.             else:
  235.                 # Write the output for non-palindromic primes
  236.                 result_str = f"[y={y_value}, P={P}]"
  237.            
  238.             # Write the result string to the file
  239.             file.write(result_str + "\n")
  240.  
  241. # Terminal Output Messages
  242. print(f"\nPlot data saved to 'plot_data.txt'\n")
  243. print(f"\nTerminal output saved to {output_filename}\n")
  244.  
  245. # Print the elapsed time in hours, minutes, and seconds format
  246. hours, remainder = divmod(elapsed_time, 3600)
  247. minutes, seconds = divmod(remainder, 60)
  248. print(f"\nTime elapsed: {int(hours)} hours, {int(minutes)} minutes, {seconds:.2f} seconds\n")
  249.  
  250.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement