use super::common::GraphView;
use std::collections::HashSet;
pub fn count_triangles(view: &GraphView) -> usize {
let mut triangle_count = 0;
for u in 0..view.node_count {
let u_neighbors: HashSet<_> = view.outgoing[u].iter()
.chain(view.incoming[u].iter())
.cloned()
.collect();
for &v in &u_neighbors {
if v <= u { continue; }
let v_neighbors: HashSet<_> = view.outgoing[v].iter()
.chain(view.incoming[v].iter())
.cloned()
.collect();
for &w in &v_neighbors {
if w <= v { continue; }
if u_neighbors.contains(&w) {
triangle_count += 1;
}
}
}
}
triangle_count
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
#[test]
fn test_triangle_counting() {
let node_count = 4;
let mut outgoing = vec![vec![]; 4];
let mut incoming = vec![vec![]; 4];
for i in 0..4 {
for j in (i+1)..4 {
outgoing[i].push(j);
incoming[j].push(i);
}
}
let view = GraphView {
node_count,
index_to_node: vec![0, 1, 2, 3],
node_to_index: HashMap::new(), outgoing,
incoming,
weights: None,
};
let count = count_triangles(&view);
assert_eq!(count, 4);
}
}