use std::{char, collections::HashMap}; pub fn word_search(board: &[Vec], words: &[&str]) -> Vec { 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::>(), ) { result.push(word.to_owned().to_owned().to_owned()); } } } } } result } fn search(row: usize, column: usize, board: &[Vec], 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 }