73 lines
2.0 KiB
Rust
73 lines
2.0 KiB
Rust
|
use std::{char, collections::HashMap};
|
||
|
|
||
|
pub fn word_search(board: &[Vec<char>], words: &[&str]) -> Vec<String> {
|
||
|
let mut first_char_to_word = HashMap::new();
|
||
|
for w in words {
|
||
|
first_char_to_word
|
||
|
.entry(w.chars().next().unwrap())
|
||
|
.or_insert(vec![])
|
||
|
.push(w);
|
||
|
}
|
||
|
|
||
|
let mut result = Vec::new();
|
||
|
|
||
|
for (rown, row) in board.iter().enumerate() {
|
||
|
for (column, ch) in row.iter().enumerate() {
|
||
|
if let Some(possible_words) = first_char_to_word.get(ch) {
|
||
|
for word in possible_words {
|
||
|
if search(
|
||
|
rown,
|
||
|
column,
|
||
|
board,
|
||
|
&word.chars().skip(1).collect::<Vec<char>>(),
|
||
|
) {
|
||
|
result.push(word.to_owned().to_owned().to_owned());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
result
|
||
|
}
|
||
|
|
||
|
fn search(row: usize, column: usize, board: &[Vec<char>], word: &[char]) -> bool {
|
||
|
if word.is_empty() {
|
||
|
return true;
|
||
|
}
|
||
|
let (first_char, other_chars) = word.split_first().unwrap();
|
||
|
|
||
|
if row > 0 {
|
||
|
if let Some(char_row) = board.get(row - 1) {
|
||
|
if char_row.get(column).unwrap() == first_char
|
||
|
&& search(row - 1, column, board, other_chars)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if let Some(char_row) = board.get(row + 1) {
|
||
|
if char_row.get(column).unwrap() == first_char
|
||
|
&& search(row + 1, column, board, other_chars)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
if let Some(char_row) = board.get(row) {
|
||
|
if column > 0
|
||
|
&& char_row.get(column - 1).unwrap() == first_char
|
||
|
&& search(row, column - 1, board, other_chars)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
if column + 1 < char_row.len()
|
||
|
&& char_row.get(column + 1).unwrap() == first_char
|
||
|
&& search(row, column + 1, board, other_chars)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
false
|
||
|
}
|