fork download
  1. use std::collections::{BTreeSet, HashMap};
  2. use std::iter::FromIterator;
  3. fn f<'a>(a: &[&'a str]) -> Vec<Vec<&'a str>> { // '
  4. fn g(a: Vec<BTreeSet<usize>>) -> Vec<BTreeSet<usize>> {
  5. for (i, j) in (0..a.len()).flat_map(|i| (i + 1..a.len()).map(move |j| (i, j))) {
  6. if !a[i].is_disjoint(&a[j]) {
  7. return g(a.iter().enumerate().filter_map(|(k, set)|
  8. if k == i {
  9. Some(BTreeSet::from_iter(a[i].union(&a[j]).cloned()))
  10. } else if k == j {
  11. None
  12. } else {
  13. Some(set.clone())
  14. }
  15. ).collect())
  16. }
  17. }
  18. a
  19. }
  20. let h = a.iter().map(|&s| s.split('=')).flatten().rev().enumerate().map(|(p, s)| (s, a.len() * 2 - p)).collect::<HashMap<_, _>>();
  21. let a = a.iter().map(|&s| s.split('=').flat_map(|k| h.get(k)).cloned().collect::<BTreeSet<_>>()).collect();
  22. let hi = h.iter().map(|(&k, &v)| (v, k)).collect::<HashMap<_, _>>();
  23. g(a).iter().map(|set| set.iter().flat_map(|i| hi.get(i)).cloned().collect()).collect()
  24. }
  25. fn main() {
  26. let v = ["a1=a2", "b1=b2", "b3=b2", "c1=c2", "e1=e2",
  27. "a3=a4", "c3=c4", "e1=e3", "a2=a4", "c3=c1",
  28. "b3=a4", "c2=d1", "a4=a5", "d2=c1", "b4=b3", "d3=c3"];
  29. println!("{:?}", f(&v));
  30. }
Success #stdin #stdout 0s 5304KB
stdin
Standard input is empty
stdout
[["a1", "a2", "b1", "b2", "b3", "a3", "a4", "a5", "b4"], ["c1", "c2", "c3", "c4", "d1", "d2", "d3"], ["e1", "e2", "e3"]]