diff --git a/src/lib/vec.rs b/src/lib/vec.rs index f459a75270a..5fbbb72d9f0 100644 --- a/src/lib/vec.rs +++ b/src/lib/vec.rs @@ -734,6 +734,31 @@ fn riter2(v: [mutable? T], f: block(uint, T)) { }; } +/* +Function: permute + +Iterate over all permutations of vector `v`. Permutations are produced in +lexicographic order with respect to the order of elements in `v` (so if `v` +is sorted then the permutations are lexicographically sorted). + +The total number of permutations produced is `len(v)!`. If `v` contains +repeated elements, then some permutations are repeated. +*/ +fn permute(v: [mutable? T], put: block([T])) { + let ln = len(v); + if ln == 0u { + put([]); + } else { + let i = 0u; + while i < ln { + let elt = v[i]; + let rest = slice(v, 0u, i) + slice(v, i+1u, ln); + permute(rest) {|permutation| put([elt] + permutation)} + i += 1u; + } + } +} + /* Function: to_ptr diff --git a/src/test/stdtest/vec.rs b/src/test/stdtest/vec.rs index de3b15d3a7b..9b29d5d1977 100644 --- a/src/test/stdtest/vec.rs +++ b/src/test/stdtest/vec.rs @@ -366,6 +366,27 @@ fn riter2() { assert i == 3; } +#[test] +fn test_permute() { + let results: [[int]]; + + results = []; + permute([]) {|v| results += [v]; } + assert results == [[]]; + + results = []; + permute([7]) {|v| results += [v]; } + assert results == [[7]]; + + results = []; + permute([1,1]) {|v| results += [v]; } + assert results == [[1,1],[1,1]]; + + results = []; + permute([5,2,0]) {|v| results += [v]; } + assert results == [[5,2,0],[5,0,2],[2,5,0],[2,0,5],[0,5,2],[0,2,5]]; +} + #[test] fn test_any_and_all() { assert (vec::any(is_three, [1u, 2u, 3u]));