use integer_sqrt::IntegerSquareRoot;
use num_traits::{PrimInt, Unsigned};
#[allow(
clippy::cast_possible_truncation,
clippy::cast_precision_loss,
clippy::cast_sign_loss
)]
pub fn uint_sqrt<T>(n: T) -> Option<T>
where
T: PrimInt + Unsigned,
{
let root = n.integer_sqrt();
(n == root * root).then_some(root)
}
#[must_use]
#[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
pub fn move_in_direction(
start: (usize, usize),
direction: (isize, isize),
dimensions: (usize, usize),
) -> Option<(usize, usize)> {
let (row, col) = start;
if row >= dimensions.0 || col >= dimensions.1 || direction == (0, 0) {
return None;
}
let (new_row, new_col) = (row as isize + direction.0, col as isize + direction.1);
(new_row >= 0
&& (new_row as usize) < dimensions.0
&& new_col >= 0
&& (new_col as usize) < dimensions.1)
.then_some((new_row as usize, new_col as usize))
}
pub fn in_direction(
start: (usize, usize),
direction: (isize, isize),
dimensions: (usize, usize),
) -> impl Iterator<Item = (usize, usize)> {
std::iter::successors(Some(start), move |current| {
move_in_direction(*current, direction, dimensions)
})
.skip(1)
}