Created
December 25, 2017 08:49
-
-
Save lloydmeta/2129ee73c24a83164e47f30e19294136 to your computer and use it in GitHub Desktop.
Given the index of a point in an Ulam Spiral, return the cartesian Coordinates in O(1)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Clone, Copy, Debug, PartialEq, Eq)] | |
pub struct Coords { | |
pub x: i64, | |
pub y: i64, | |
} | |
/// Given an Ulam spiral index, returns the Cartesian coordiantes | |
/// for it. | |
/// | |
/// # Examples | |
/// ``` | |
/// assert_eq!(idx_to_coords(22), Ok(Coords { x: -1, y: -2 })); | |
/// ``` | |
pub fn idx_to_coords(idx: u64) -> Result<Coords, &'static str> { | |
if idx > 0 { | |
let r = { | |
let idx_to_check = idx as i64; | |
let layer = (((idx as f64).sqrt() - 1f64) / 2f64).ceil() as i64; | |
let points_in_layer = 2 * layer + 1; | |
// this is the greatest index in the layer | |
let lower_right_idx = points_in_layer.pow(2); | |
let side_width = points_in_layer - 1; | |
if idx_to_check >= (lower_right_idx - side_width) { | |
// we are on the south-side of the layer | |
Coords { | |
x: layer - (lower_right_idx - idx_to_check), | |
y: -layer, | |
} | |
} else { | |
let lower_left_idx = lower_right_idx - side_width; | |
if idx_to_check >= (lower_left_idx - side_width) { | |
Coords { | |
x: -layer, | |
y: -layer + (lower_left_idx - idx_to_check), | |
} | |
} else { | |
let upper_left_idx = lower_left_idx - side_width; | |
if idx_to_check >= upper_left_idx - side_width { | |
Coords { | |
x: -layer + (upper_left_idx - idx_to_check), | |
y: layer, | |
} | |
} else { | |
let upper_right_idx = upper_left_idx - side_width; | |
Coords { | |
x: layer, | |
y: layer - (upper_right_idx - idx_to_check), | |
} | |
} | |
} | |
} | |
}; | |
Ok(r) | |
} else { | |
Err("Idx must be greater than 0") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment