Skip to content

Instantly share code, notes, and snippets.

@RandyMcMillan
Forked from rust-play/playground.rs
Last active November 16, 2025 03:01
Show Gist options
  • Select an option

  • Save RandyMcMillan/77a8880f534c40332ab0eb29193f0a72 to your computer and use it in GitHub Desktop.

Select an option

Save RandyMcMillan/77a8880f534c40332ab0eb29193f0a72 to your computer and use it in GitHub Desktop.
3D-Ulam-Spiral.rs
// a 3D Ulam Spiral
// projected onto a 2D grid,
// marking primes with their Z-index.
/// Generates a boolean vector where `is_prime[i]` is true if `i` is a prime number (Sieve of Eratosthenes).
fn sieve_of_eratosthenes(max_value: usize) -> Vec<bool> {
if max_value < 2 { return vec![]; }
let mut is_prime = vec![true; max_value + 1];
is_prime[0] = false;
is_prime[1] = false;
let mut p = 2;
while p * p <= max_value {
if is_prime[p] {
let mut i = p * p;
while i <= max_value {
is_prime[i] = false;
i += p;
}
}
p += 1;
}
is_prime
}
/// Generates the N x N grid projection by running the spiral across multiple Z-planes (max_z).
fn generate_3d_projection(n: usize, max_z: usize) -> (Vec<Vec<char>>, usize) {
if n == 0 || max_z == 0 { return (vec![], 0); }
let dim = if n % 2 == 0 { n + 1 } else { n };
let total_cells = dim * dim * max_z;
let is_prime = sieve_of_eratosthenes(total_cells);
let mut current_num = 1;
// Initialize the 2D grid with a placeholder character (e.g., space or dot)
let mut grid: Vec<Vec<char>> = vec![vec!['.'; dim]; dim];
for z in 0..max_z {
// --- Spiral Setup for the current Z-plane ---
let mut x = dim / 2;
let mut y = dim / 2;
let mut step_length = 1;
let mut turns_made = 0;
let mut direction = 0; // 0: Right, 1: Up, 2: Left, 3: Down
let dx = [1, 0, -1, 0];
let dy = [0, -1, 0, 1];
let cells_in_plane = dim * dim;
let mut cells_filled_in_plane = 0;
// Handle the center cell first
if current_num <= total_cells {
if current_num < is_prime.len() && is_prime[current_num] {
// Mark center cell with Z-index
// Use the Z index modulo 10 to get a single digit '0' through '9'
grid[y][x] = (b'0' + (z % 10) as u8) as char;
} else {
// If not prime, leave the existing mark (or dot if it's the first time)
if grid[y][x] == ' ' || grid[y][x] == '.' {
grid[y][x] = '.';
}
}
current_num += 1;
cells_filled_in_plane += 1;
}
// --- Core Spiral Generation for this Z-plane ---
while cells_filled_in_plane < cells_in_plane {
for _ in 0..step_length {
if current_num > total_cells {
return (grid, total_cells);
}
// Update position (x, y)
x = (x as isize + dx[direction]) as usize;
y = (y as isize + dy[direction]) as usize;
// Mark the cell if it's a prime
if current_num < is_prime.len() && is_prime[current_num] {
// Mark with Z-index
grid[y][x] = (b'0' + (z % 10) as u8) as char;
} else {
// If not prime, leave the existing mark (or dot if it's the first time)
if grid[y][x] == ' ' || grid[y][x] == '.' {
grid[y][x] = '.';
}
}
current_num += 1;
cells_filled_in_plane += 1;
if cells_filled_in_plane >= cells_in_plane { break; }
}
if cells_filled_in_plane >= cells_in_plane { break; }
// Change direction and increase step length
direction = (direction + 1) % 4;
turns_made += 1;
if turns_made % 2 == 0 {
step_length += 1;
}
}
}
(grid, total_cells)
}
/// Prints the resulting Ulam spiral projection to the console.
fn print_projection(grid: &Vec<Vec<char>>, max_num: usize, n: usize, max_z: usize) {
println!("\n--- 3D Ulam Spiral Projection onto X-Y Plane ---");
println!("Grid Size: {n}x{n} | Z-Planes: 0 to {} | Max Number: {}", max_z - 1, max_num);
println!("-----------------------------------------------");
for row in grid {
for &cell in row {
print!("{} ", cell);
}
println!();
}
println!("-----------------------------------------------");
println!("Key: '.' = Composite or Unmarked Prime (Z=0)");
println!(" '0' - '{}' = Prime from that Z-Plane Index", max_z.min(9));
}
fn main() {
let n = 38; // Size of the 2D plane (N x N)
let max_z = n*n; // Number of Z-planes to fill (Z=0, Z=1, Z=2)
println!("Generating 3D Ulam structure for size {}x{}x{}...", n, n, max_z);
let (spiral_grid, max_num) = generate_3d_projection(n, max_z);
print_projection(&spiral_grid, max_num, n, max_z);
}
@RandyMcMillan
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment