Advertisement
Python253

ulam_py2y41_v2

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