$" = ''; chomp( my @edges = grep /\w -- \w/, ); my @nodes = sort { $a cmp $b } uniq( map /\w/g, @edges ); for my $node ( @nodes ) { my $edge_rx = qr/$node -- (\w)/; my @other_nodes = map /$edge_rx/ ? $1 : (), @edges; my $third_edge = qr/[@other_nodes] -- [@other_nodes]/; for ( grep /$third_edge/, @edges ) { my @nodes = sort { $a cmp $b } $node, /\w/g; $triangles{"@nodes"} = undef; } } for ( sort keys %triangles ) { print join( " -- ", split // ), "\n"; } sub uniq { my %seen; grep !$seen{$_}++, @_ } __DATA__ graph triangles { A -- B A -- C A -- D A -- E B -- A B -- C B -- D B -- E B -- F B -- H B -- J B -- I C -- A C -- B C -- D C -- E C -- F C -- I D -- A D -- B D -- C D -- E D -- G D -- I E -- A E -- B E -- C E -- D E -- G E -- H E -- I E -- J F -- B F -- C F -- H F -- I F -- J G -- A G -- D G -- E G -- H G -- I G -- J H -- B H -- E H -- F H -- G H -- I H -- J I -- B I -- C I -- E I -- F I -- G I -- H I -- J J -- A J -- B J -- D J -- E J -- F J -- G J -- H J -- I }