Challenge 58
Generate All String Permutations
Write a function generate_permutations that generates all possible permutations of a given string. A permutation is a rearrangement of the characters in the string, where each character is used exactly once.
Write your solution below
// Rust Bytes Issue 67: Generate All String Permutations pub fn generate_permutations(s: &str) -> Vec<String> { // your code goes here } #[cfg(test)] mod tests { use super::*; fn run_test(input: &str, expected: Vec<&str>, test_name: &str) { let mut result = generate_permutations(input); let mut expected_vec: Vec<String> = expected.iter().map(|&s| s.to_string()).collect(); result.sort(); expected_vec.sort(); assert_eq!( result, expected_vec, "Test case '{}' failed: input={}, expected={:?}, got={:?}", test_name, input, expected_vec, result ); println!( "Test case '{}' passed: input={}, output={:?}", test_name, input, result ); } #[test] fn test_basic_aabb() { run_test( "aabb", vec!["aabb", "abab", "abba", "baab", "baba", "bbaa"], "basic_aabb", ); } #[test] fn test_basic_xyz() { run_test( "xyz", vec!["xyz", "xzy", "yxz", "yzx", "zxy", "zyx"], "basic_xyz", ); } #[test] fn test_basic_aabc() { run_test( "aabc", vec![ "aabc", "aacb", "abac", "abca", "acab", "acba", "baac", "baca", "bcaa", "caab", "caba", "cbaa", ], "basic_aabc", ); } #[test] fn test_edge_empty() { run_test("", vec![""], "edge_empty"); } #[test] fn test_edge_single_char() { run_test("a", vec!["a"], "edge_single_char"); } #[test] fn test_edge_all_same() { run_test("aaa", vec!["aaa"], "edge_all_same"); } #[test] fn test_edge_unique_chars() { run_test( "abc", vec!["abc", "acb", "bac", "bca", "cab", "cba"], "edge_unique_chars", ); } #[test] fn test_repeated_two() { run_test("aba", vec!["aab", "aba", "baa"], "repeated_two"); } #[test] fn test_repeated_three() { run_test( "abbc", vec![ "abbc", "abcb", "acbb", "babc", "bacb", "bbac", "bbca", "bcab", "bcba", "cabb", "cbab", "cbba", ], "repeated_three", ); } #[test] fn test_repeated_multiple() { run_test( "aabbc", vec![ "aabbc", "aabcb", "aacbb", "ababc", "abacb", "abbac", "abbca", "abcab", "abcba", "acabb", "acbab", "acbba", "baabc", "baacb", "babac", "babca", "bacab", "bacba", "bbaac", "bbaca", "bbcaa", "bcaab", "bcaba", "bcbaa", "caabb", "cabab", "cabba", "cbaab", "cbaba", "cbbaa", ], "repeated_multiple", ); } #[test] fn test_digits() { run_test("121", vec!["112", "121", "211"], "digits"); } #[test] fn test_special_chars() { run_test( "!@#", vec!["!@#", "!#@", "@!#", "@#!", "#!@", "#@!"], "special_chars", ); } }
Solution
Click to Show/Hide Solution
#![allow(unused)] fn main() { // Rust Bytes Issue 67: Generate All String Permutations pub fn generate_permutations(s: &str) -> Vec<String> { fn perms_rec(out: &mut Vec<String>, s: &mut [char], n: usize) { if n <= 1 { out.push(s.iter().collect()); return; } for i in 0..n { s.swap(i, n - 1); perms_rec(out, s, n - 1); s.swap(i, n - 1); } } let mut s: Vec<char> = s.chars().collect(); let mut out = Vec::new(); let n = s.len(); perms_rec(&mut out, &mut s, n); out.sort(); out.dedup(); out } #[cfg(test)] mod tests { use super::*; fn run_test(input: &str, expected: Vec<&str>, test_name: &str) { let mut result = generate_permutations(input); let mut expected_vec: Vec<String> = expected.iter().map(|&s| s.to_string()).collect(); result.sort(); expected_vec.sort(); assert_eq!( result, expected_vec, "Test case '{}' failed: input={}, expected={:?}, got={:?}", test_name, input, expected_vec, result ); println!( "Test case '{}' passed: input={}, output={:?}", test_name, input, result ); } #[test] fn test_basic_aabb() { run_test( "aabb", vec!["aabb", "abab", "abba", "baab", "baba", "bbaa"], "basic_aabb", ); } #[test] fn test_basic_xyz() { run_test( "xyz", vec!["xyz", "xzy", "yxz", "yzx", "zxy", "zyx"], "basic_xyz", ); } #[test] fn test_basic_aabc() { run_test( "aabc", vec![ "aabc", "aacb", "abac", "abca", "acab", "acba", "baac", "baca", "bcaa", "caab", "caba", "cbaa", ], "basic_aabc", ); } #[test] fn test_edge_empty() { run_test("", vec![""], "edge_empty"); } #[test] fn test_edge_single_char() { run_test("a", vec!["a"], "edge_single_char"); } #[test] fn test_edge_all_same() { run_test("aaa", vec!["aaa"], "edge_all_same"); } #[test] fn test_edge_unique_chars() { run_test( "abc", vec!["abc", "acb", "bac", "bca", "cab", "cba"], "edge_unique_chars", ); } #[test] fn test_repeated_two() { run_test("aba", vec!["aab", "aba", "baa"], "repeated_two"); } #[test] fn test_repeated_three() { run_test( "abbc", vec![ "abbc", "abcb", "acbb", "babc", "bacb", "bbac", "bbca", "bcab", "bcba", "cabb", "cbab", "cbba", ], "repeated_three", ); } #[test] fn test_repeated_multiple() { run_test( "aabbc", vec![ "aabbc", "aabcb", "aacbb", "ababc", "abacb", "abbac", "abbca", "abcab", "abcba", "acabb", "acbab", "acbba", "baabc", "baacb", "babac", "babca", "bacab", "bacba", "bbaac", "bbaca", "bbcaa", "bcaab", "bcaba", "bcbaa", "caabb", "cabab", "cabba", "cbaab", "cbaba", "cbbaa", ], "repeated_multiple", ); } #[test] fn test_digits() { run_test("121", vec!["112", "121", "211"], "digits"); } #[test] fn test_special_chars() { run_test( "!@#", vec!["!@#", "!#@", "@!#", "@#!", "#!@", "#@!"], "special_chars", ); } } }