use std::collections::HashSet;
use crate::{direction::DIRECTIONS_90_DEG, point::Point2};
pub fn find_character_first_vec_string(input: Vec<String>, target: char) -> (usize, usize) {
input
.iter()
.enumerate()
.filter_map(|(row_idx, row)| {
row.chars().enumerate().find_map(|(col_idx, c)| {
if c == target {
Some((col_idx, row_idx))
} else {
None
}
})
})
.next()
.unwrap()
}
pub fn find_character_all_occurences_vec_string(
input: Vec<String>,
target: char,
) -> Vec<(usize, usize)> {
input
.iter()
.enumerate()
.fold(Vec::new(), |mut vec, (row_idx, row)| {
row.chars().enumerate().for_each(|(col_idx, c)| {
if c == target {
vec.push((col_idx, row_idx))
}
});
vec
})
}
pub fn find_character_first_grid(input: Vec<Vec<char>>, target: char) -> (usize, usize) {
input
.iter()
.enumerate()
.filter_map(|(row_idx, row)| {
row.iter().enumerate().find_map(|(col_idx, c)| {
if *c == target {
Some((col_idx, row_idx))
} else {
None
}
})
})
.next()
.unwrap()
}
pub fn find_character_all_occurences_grid(
input: Vec<Vec<char>>,
target: char,
) -> Vec<(usize, usize)> {
input
.iter()
.enumerate()
.fold(Vec::new(), |mut vec, (row_idx, row)| {
row.iter().enumerate().for_each(|(col_idx, c)| {
if *c == target {
vec.push((col_idx, row_idx))
}
});
vec
})
}
pub fn find_number_first(input: Vec<Vec<usize>>, target: usize) -> (usize, usize) {
input
.iter()
.enumerate()
.filter_map(|(row_idx, row)| {
row.iter().enumerate().find_map(|(col_idx, &n)| {
if n == target {
Some((col_idx, row_idx))
} else {
None
}
})
})
.next()
.unwrap()
}
pub fn find_number_all_occurences(input: Vec<Vec<usize>>, target: usize) -> Vec<(usize, usize)> {
input
.iter()
.enumerate()
.fold(Vec::new(), |mut vec, (row_idx, row)| {
row.iter().enumerate().for_each(|(col_idx, &n)| {
if n == target {
vec.push((col_idx, row_idx))
}
});
vec
})
}
pub fn get_regions_from_grid(grid: &[Vec<char>]) -> Vec<(char, Vec<Point2>)> {
let mut regions = Vec::new();
let mut seen = HashSet::new();
let dimensions = (grid[0].len() as isize, grid.len() as isize);
for (y, r) in grid.iter().enumerate() {
for (x, c) in r.iter().enumerate() {
let char_point = Point2::new(x as isize, y as isize);
if seen.contains(&char_point) {
continue;
}
let mut elements = Vec::from([char_point]);
seen.insert(char_point);
let mut queue = Vec::from([char_point]);
while let Some(point) = queue.pop() {
for d in DIRECTIONS_90_DEG {
let next_pos =
Point2::new(point.x + d.to_vector2().x, point.y + d.to_vector2().y);
if next_pos.x >= 0
&& next_pos.x < dimensions.0
&& next_pos.y >= 0
&& next_pos.y < dimensions.1
&& grid[next_pos.y as usize][next_pos.x as usize] == *c
&& !seen.contains(&next_pos)
{
seen.insert(next_pos);
queue.push(next_pos);
elements.push(next_pos);
}
}
}
elements.sort_by_key(|p| (p.y, p.x));
regions.push((*c, elements))
}
}
regions
}