Each of your three sequences can be understood as a clique in a multigraph. Within a clique, every vertex is connected to every other vertex.
The following graph represents your sample case with the edges in each clique colored red, blue, and green, respectively.

As you have already shown, we can classify pairs of vertices according to the number of edges between them. In the illustration, we can see that four pairs of vertices are connected by two edges each, and four other pairs of vertices are connected by one edge each.
We can go on to classify vertices according to the number of cliques in which they appear. In some sense we are ranking vertices according to their connectedness. A vertex that appears in k
cliques can be thought of as connected to the same degree as other vertices that appear in k
cliques. In the image, we see three groups of vertices: vertex 3 appears in three cliques; vertices 1, 2, and 4 each appear in two cliques; vertex 5 appears in one clique.
The Go program below computes the edge classification as well as the vertex classification. The input to the program contains, on the first line, the number of vertices n
and the number of cliques m
. We assume that the vertices are numbered from 1 to n
. Each of the succeeding m
lines of input is a space-separated list of vertices belonging to a clique. Thus, the problem instance given in the question is represented by this input:
5 3
1 2 3 4
4 3 5
2 1 3
The corresponding output is:
Number of edges between pairs of vertices:
2 edges: (1, 2) (1, 3) (2, 3) (3, 4)
1 edge: (1, 4) (2, 4) (3, 5) (4, 5)
Number of cliques in which a vertex appears:
3 cliques: 3
2 cliques: 1 2 4
1 clique: 5
And here is the Go program:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
// Set up input and output.
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
// Get the number of vertices and number of cliques from the first line.
line, err := reader.ReadString('\n')
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading first line: %s\n", err)
return
}
var numVertices, numCliques int
numScanned, err := fmt.Sscanf(line, "%d %d", &numVertices, &numCliques)
if numScanned != 2 || err != nil {
fmt.Fprintf(os.Stderr, "Error parsing input parameters: %s\n", err)
return
}
// Initialize the edge counts and vertex counts.
edgeCounts := make([][]int, numVertices+1)
for u := 1; u <= numVertices; u++ {
edgeCounts[u] = make([]int, numVertices+1)
}
vertexCounts := make([]int, numVertices+1)
// Read each clique and update the edge counts.
for c := 0; c < numCliques; c++ {
line, err = reader.ReadString('\n')
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading clique: %s\n", err)
return
}
tokens := strings.Split(strings.TrimSpace(line), " ")
clique := make([]int, len(tokens))
for i, token := range tokens {
u, err := strconv.Atoi(token)
if err != nil {
fmt.Fprintf(os.Stderr, "Atoi error: %s\n", err)
return
}
vertexCounts[u]++
clique[i] = u
for j := 0; j < i; j++ {
v := clique[j]
edgeCounts[u][v]++
edgeCounts[v][u]++
}
}
}
// Compute the number of edges between each pair of vertices.
count2edges := make([][][]int, numCliques+1)
for u := 1; u < numVertices; u++ {
for v := u + 1; v <= numVertices; v++ {
count := edgeCounts[u][v]
count2edges[count] = append(count2edges[count],
[]int{u, v})
}
}
writer.WriteString("Number of edges between pairs of vertices:\n")
for count := numCliques; count >= 1; count-- {
edges := count2edges[count]
if len(edges) == 0 {
continue
}
label := "edge"
if count > 1 {
label += "s:"
} else {
label += ": "
}
writer.WriteString(fmt.Sprintf("%5d %s", count, label))
for _, edge := range edges {
writer.WriteString(fmt.Sprintf(" (%d, %d)",
edge[0], edge[1]))
}
writer.WriteString("\n")
}
// Group vertices according to the number of clique memberships.
count2vertices := make([][]int, numCliques+1)
for u := 1; u <= numVertices; u++ {
count := vertexCounts[u]
count2vertices[count] = append(count2vertices[count], u)
}
writer.WriteString("\nNumber of cliques in which a vertex appears:\n")
for count := numCliques; count >= 1; count-- {
vertices := count2vertices[count]
if len(vertices) == 0 {
continue
}
label := "clique"
if count > 1 {
label += "s:"
} else {
label += ": "
}
writer.WriteString(fmt.Sprintf("%5d %s", count, label))
for _, u := range vertices {
writer.WriteString(fmt.Sprintf(" %d", u))
}
writer.WriteString("\n")
}
}