Created
January 21, 2022 01:50
-
-
Save lissahyacinth/bce631209b7e324ce63519dad61a6755 to your computer and use it in GitHub Desktop.
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
pub enum Direction { | |
Left, | |
Right, | |
Up, | |
Down, | |
UpperLeft, | |
UpperRight, | |
DownLeft, | |
DownRight, | |
} | |
type Edge = (usize, usize); | |
fn left_edges(dimensions: (usize, usize)) -> Vec<Edge> { | |
let (height, width) = dimensions; | |
let mut results: Vec<Edge> = Vec::with_capacity(height * width - width); | |
for x in (width..=(height * width)).step_by(width) { | |
for y in 1..width { | |
results.push((x - y, x - (y + 1))) | |
} | |
} | |
results | |
} | |
fn right_edges(dimensions: (usize, usize)) -> Vec<Edge> { | |
let (height, width) = dimensions; | |
let mut results: Vec<Edge> = Vec::with_capacity(height * width - width); | |
for x in (0..(height * width)).step_by(width) { | |
for y in 0..(width - 1) { | |
results.push((x + y, x + (y + 1))) | |
} | |
} | |
results | |
} | |
fn down_edges(dimensions: (usize, usize)) -> Vec<Edge> { | |
let (height, width) = dimensions; | |
let mut results: Vec<Edge> = Vec::with_capacity(height * width - width); | |
for x in 0..width { | |
for y in 0..(height - 1) { | |
results.push((width * y + x, width * (y + 1) + x)) | |
} | |
} | |
results | |
} | |
fn up_edges(dimensions: (usize, usize)) -> Vec<Edge> { | |
let (height, width) = dimensions; | |
let mut results: Vec<Edge> = Vec::with_capacity(height * width - width); | |
for x in 0..width { | |
for y in 0..(height - 1) { | |
results.push((width * y + x, width * (y + 1) + x)) | |
} | |
} | |
results | |
} | |
// Pursue LeftHandSide Edge -> Bottom Edge | |
fn upper_left_edges(dimensions: (usize, usize)) -> Vec<Edge> { | |
let (height, width) = dimensions; | |
let mut results: Vec<Edge> = Vec::with_capacity(height * width - width); | |
// Begin on second row | |
for (row, idx) in (0..(height * width)).step_by(width).enumerate().skip(1) { | |
for y in 0..row { | |
results.push(((idx - y * width + (y)), (idx - (y + 1) * width + (y + 1)))); | |
} | |
} | |
// Pursue Bottom left Edge -> Bottom Right Edge. | |
// Skip first element as it's covered by first pursuit. | |
// Skip last element as it cannot have diagonal edge. | |
for (col, idx) in (((height - 1) * width)..(height * width)) | |
.enumerate() | |
.skip(1) | |
.take(width - 1) | |
{ | |
for y in 0..(height - 1 - col) { | |
println!("x: {} y: {}", idx, y); | |
results.push(((idx - y * width + (y)), (idx - (y + 1) * width + (y + 1)))); | |
} | |
} | |
results | |
} | |
fn find_edges(dimensions: (usize, usize), directions: Vec<Direction>) -> Vec<Edge> { | |
directions | |
.into_iter() | |
.map(|direction| match direction { | |
Direction::Left => left_edges(dimensions), | |
Direction::Right => right_edges(dimensions), | |
Direction::Up => todo!(), | |
Direction::Down => down_edges(dimensions), | |
Direction::UpperLeft => upper_left_edges(dimensions), | |
Direction::UpperRight => todo!(), | |
Direction::DownLeft => todo!(), | |
Direction::DownRight => todo!(), | |
}) | |
.flatten() | |
.collect() | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::*; | |
#[test] | |
fn left_edges_3_3() { | |
// 0 1 2 | |
// 3 4 5 | |
// 6 7 8 | |
let dims: (usize, usize) = (3, 3); | |
let direction: Direction = Direction::Left; | |
let res: Vec<Edge> = vec![(2, 1), (1, 0), (5, 4), (4, 3), (8, 7), (7, 6)]; | |
assert_eq!(res, find_edges(dims, vec![direction])); | |
} | |
#[test] | |
fn left_edges_2_4() { | |
// 0 1 2 3 | |
// 4 5 6 7 | |
let dims: (usize, usize) = (2, 4); | |
let direction: Direction = Direction::Left; | |
let res: Vec<Edge> = vec![(3, 2), (2, 1), (1, 0), (7, 6), (6, 5), (5, 4)]; | |
assert_eq!(res, find_edges(dims, vec![direction])); | |
} | |
#[test] | |
fn right_edges_4_4() { | |
// 0 1 2 3 | |
// 4 5 6 7 | |
// 8 9 10 11 | |
// 12 13 14 15 | |
let dims: (usize, usize) = (4, 4); | |
let direction: Direction = Direction::Right; | |
let res: Vec<Edge> = vec![ | |
(0, 1), | |
(1, 2), | |
(2, 3), | |
(4, 5), | |
(5, 6), | |
(6, 7), | |
(8, 9), | |
(9, 10), | |
(10, 11), | |
(12, 13), | |
(13, 14), | |
(14, 15), | |
]; | |
assert_eq!(res, find_edges(dims, vec![direction])); | |
} | |
#[test] | |
fn right_edges_2_4() { | |
// 0 1 2 3 | |
// 4 5 6 7 | |
let dims: (usize, usize) = (2, 4); | |
let direction: Direction = Direction::Right; | |
let res: Vec<Edge> = vec![(0, 1), (1, 2), (2, 3), (4, 5), (5, 6), (6, 7)]; | |
assert_eq!(res, find_edges(dims, vec![direction])); | |
} | |
#[test] | |
fn down_edges_2_3() { | |
// 0 1 2 | |
// 3 4 5 | |
let dims: (usize, usize) = (2, 3); | |
let direction: Direction = Direction::Down; | |
let res: Vec<Edge> = vec![(0, 3), (1, 4), (2, 5)]; | |
assert_eq!(res, find_edges(dims, vec![direction])); | |
} | |
#[test] | |
fn down_edges_3_3() { | |
// 0 1 2 | |
// 3 4 5 | |
// 6 7 8 | |
let dims: (usize, usize) = (3, 3); | |
let direction: Direction = Direction::Down; | |
let res: Vec<Edge> = vec![(0, 3), (3, 6), (1, 4), (4, 7), (2, 5), (5, 8)]; | |
assert_eq!(res, find_edges(dims, vec![direction])); | |
} | |
#[test] | |
fn upper_left_3_3() { | |
// 0 1 2 | |
// 3 4 5 | |
// 6 7 8 | |
let dims: (usize, usize) = (3, 3); | |
let direction: Direction = Direction::UpperLeft; | |
let res: Vec<Edge> = vec![(3, 1), (6, 4), (4, 2), (7, 5)]; | |
assert_eq!(res, find_edges(dims, vec![direction])); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment