All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.io.nacular.doodle.utils.Path.kt Maven / Gradle / Ivy

There is a newer version: 0.10.4
Show newest version
package io.nacular.doodle.utils

import kotlin.math.min

/**
 * Created by Nicholas Eddy on 3/23/18.
 */
public class Path(private val items: List): Iterable {
    public constructor(item: T): this(listOf(item))
    public constructor(       ): this(listOf()    )

    public val top   : T?  = items.firstOrNull()
    public val bottom: T?  = items.lastOrNull ()
    public val depth : Int = items.size

    public val parent: Path? by lazy { if (items.isNotEmpty()) Path(items.dropLast(1)) else null }

    private val hashCode = items.hashCode()

    public operator fun get(index: Int): T = items[index]

    public infix fun ancestorOf(path: Path): Boolean {
        if (depth >= path.depth) {
            return false
        }

        items.forEachIndexed { index, item ->
            if (item != path.items[index]) {
                return false
            }
        }

        return true
    }

    public operator fun plus(node: T): Path = Path(items + node)

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is Path<*>) return false

        // Kotlin list equals is not as efficient
        return items.size == other.items.size && items == other.items
    }

    public fun overlappingRoot(other: Path): Path {
        val result = mutableListOf()

        val depth = min(depth, other.depth)

        repeat(depth) {
            if (other.items[it] == items[it]) {
                result += items[it]
            }
        }

        return Path(result)
    }

    public fun nonOverlappingStem(other: Path): List {
        val result = mutableListOf()

        val smallestDepth = min(depth, other.depth)

        repeat(smallestDepth) {
            if (other.items[it] != items[it]) {
                result += items[it]
            }
        }

        (smallestDepth until depth).forEach {
            result += items[it]
        }

        return result
    }

    override fun hashCode(): Int         = hashCode
    override fun iterator(): Iterator = items.iterator()
    override fun toString(): String      = items.toString()
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy