August 27, 2024

P88 - Connected components.

Write a function that splits a graph into its connected components.

> "[a-b, c-d]".toGraph().components()
[[a-b], [c-d]]

kotlin

package org.kotlin99.graphs

import com.natpryce.hamkrest.assertion.assertThat
import org.junit.Test
import org.kotlin99.common.containsAll

fun <V, L> Graph<V, L>.components(): List<Graph<V, L>> {
    return nodes.keys.fold(emptyList()) { result, nodeValue ->
        if (result.any { it.nodes.contains(nodeValue) }) {
            result
        } else {
            val nodeValues = nodesByDepthFrom(nodeValue)
            val newGraph = Graph(
                nodes.values.filter { nodeValues.contains(it.value) },
                edges.filter { edge -> nodeValues.any { edge.target(nodes[it]!!) != null } }
            )
            result + newGraph
        }
    }
}

class P88Test {
    @Test fun `find connected components of a graph`() {
        assertThat("[a-b]".toGraph().components(), containsAll(listOf(
            "[a-b]".toGraph()
        )))
        assertThat("[a-b, c-d]".toGraph().components(), containsAll(listOf(
            "[a-b]".toGraph(),
            "[c-d]".toGraph()
        )))
    }
}
Be first to comment
Leave a reply