Problem:
Score : 300 points

Problem Statement

You are given a grid of squares with H horizontal rows and W vertical columns, where each square is painted white or black.
HW characters from A_{11} to A_{HW} represent the colors of the squares.
A_{ij} is # if the square at the i-th row from the top and the j-th column from the left is black, and A_{ij} is . if that square is white.

We will repeatedly perform the following operation until all the squares are black:

Every white square that shares a side with a black square, becomes black.

Find the number of operations that will be performed.
The initial grid has at least one black square.

Constraints

1 \leq H,W \leq 1000

A_{ij} is # or ..

The given grid has at least one black square.

Input

Input is given from Standard Input in the following format:

H W
A_{11}A_{12}...A_{1W}
:
A_{H1}A_{H2}...A_{HW}

Output

Print the number of operations that will be performed.

Sample Input 1

3 3
...
.#.
...

Sample Output 1

2

After one operation, all but the corners of the grid will be black. After one more operation, all the squares will be black.

Sample Input 2

6 6
..#..#
......
#..#..
......
.#....
....#.

Sample Output 2

3

Solution in Kotlin (1.0.0) (judge verdict: Wrong Answer)

import java.util.*
fun main(args : Array<String>) {
    val (H, W) = readLine()!!.split(" ").map { it.toInt() }

    val points = mutableListOf<KDStub>()
    (0..(H-1)).forEach { h ->
        readLine()!!.forEachIndexed { w, c ->
            if (c == '#') {
                val doubleH = h.toDouble()
                val doubleW = w.toDouble()
                points.add(KDStub(doubleH, doubleW, doubleArrayOf(doubleH, doubleW), 2))
            } else {
            }
        }
    }

    val kdTree = KDTree(points)

    // O(HWlog(NW))
    var maxDistance = 0
    (0..(H-1)).forEach {h ->
        (0..(W-1)).forEach { w ->
            val doubleH = h.toDouble()
            val doubleW = w.toDouble()
            val point = KDStub(doubleH, doubleW, doubleArrayOf(doubleH, doubleW), 2)
            val closestPoint = kdTree.getNearestNeighbors(1, point)!![0]
            val distance = (Math.abs(closestPoint.coordinates[0] - h) + Math.abs(closestPoint.coordinates[1] - w)).toInt()
            if (distance > maxDistance) {
                maxDistance = distance
            }
        }
    }

    println(maxDistance)
}

fun abs(num: Int) : Int {
    if (num < 0) {
        return num * -1
    }
    return num
}



/**
 * Abstraction used to run algorithms such as nearest neighbor
 * and radial search on a collection of nodes organized into a KDTree.
 *
 * @author emc3
 *
 * @param <KDType>
</KDType> */
class KDTree<KDType : KDimensionable> {

     var _root: KDNode? = null
    /**
     * This was the old constructor.
     * Used recursiveBuild() instead of recursiveBuildFaster()
     */
    /*
	public KDTree(Collection<KDType> collection) {
		this(collection.iterator().next().getNumDimensions()); //call default constructor with dimension of first object in list.

		_root = this.recursiveBuild(collection, 0); //build a new KDTree from the collection.
	}
	*/


    /**
     * @return the number of dimensions held
     * by the nodes of this tree.
     */
    var numDimensions = 0
         set //number of dimensions
     var _size: Long = 0
     val bounds: MutableList<MinMaxPair>


     var _neighborList: NeighborList? = null

    /**
     * This method is only used for testing.
     * @return the KDimensionable object stored at the root node.
     */
    val rootObject: KDType?
        get() = if (_root != null) _root!!.kdObject else null

    /**
     * Default constructor.<br></br>
     * Initializes the root node to null, and sets the
     * number of dimensions this KD tree will hold to the
     * specified integer.
     *
     * @param k -	The number of dimensions that
     * this KDTree will hold.
     */
    constructor(k: Int) {
        _root = null
        _size = 0
        if (k > 0)
            numDimensions = k
        else
            System.err.println("ERROR: KDTree constructor: Dimension must be at least 1")
        bounds = ArrayList(numDimensions)
    }

    /**
     * Alternate constructor.<br></br>
     * Calls the default constructor, which initializes the root node to null.
     * Also, the number of dimensions of the FIRST object in the collection
     * will be used to set the KDTree's number of dimension. Therefore this
     * constructor assumes that the dimension is the same for each
     * KDimensionable object in the list.
     *
     * @param collection -	A collection of KDimensionable objects that will
     * be used to create the tree.
     */
    constructor(collection: Collection<KDType>) : this(collection.iterator().next().numDimensions) {
        val superList = ArrayList<List<KDType>>(numDimensions)
        for (i in 0 until numDimensions) {
            val l = ArrayList(collection)
            val comparator = KDimensionComparator(i) //compare nodes on axis i
            Collections.sort(l, comparator) //sort the list using comparator : ascending by axis i
            val min = l[0].coordinates[i]
            val max = l[l.size - 1].coordinates[i]
            bounds.add(MinMaxPair(min, max))
            superList.add(l)
        }
        _root = this.recursiveBuildFaster(superList, 0) //build a new KDTree from the collection.
    }//call default constructor with dimension of first object in list.

    fun getMax(axis: Int): Double {
        return bounds[axis].max
    }

    fun getMin(axis: Int): Double {
        return bounds[axis].min
    }


    /**
     * This method takes a collection of objects that implement
     * KDimensionable and recursively builds a balanced KD Tree
     * from them.
     *
     * If the KDTree's _k field (number of dimensions) has not been set,
     * Or if the depth (for whatever hellish reason) is negative,
     * Or if the list is empty,
     * an error message will print to STDERROR.
     *
     *
     * @param list - The list of KDimensionable objects
     * @param depth - The depth at which to add the nodes
     */
    fun recursiveBuild(collection: Collection<KDType>, depth: Int): KDNode? {
        val list: List<KDType>
        if (collection is List<*>)
            list = collection as List<KDType> //collection is already a List : cast it
        else
            list = ArrayList(collection) //build list from the collection
        val size = list.size

        if (numDimensions < 1) {
            System.err.println("ERROR: KDTree.recursiveBuild(): Number of Dimensions has not been defined.")
            return null
        }
        if (depth < 0) {
            System.err.println("ERROR: KDTree.recursiveBuild(): Cannot build tree from a negative depth!")
            return null
        }
        if (size == 0) {
            System.err.println("ERROR: KDTree.recursiveBuild(): Cannot build tree from an empty list.")
            return null
        }

        val axis = depth % numDimensions    //the 'axis' is the dimension that the nodes should be compared by.
        //it is determined by the current depth

        val comparator = KDimensionComparator(axis) //new comparator for each depth's axis
        Collections.sort(list, comparator) //sort the list : ascending by axis

        //split list by median
        val median: KDType
        val mid = size / 2 //floor of size/2
        median = list[mid] //get median object

        //create node, split list around median and recur
        //if there is only one node left in the list, it's our median,
        //so we're done with building the tree and we can return the
        //last node which we just created from the median.
        val node = KDNode(median)
        if (depth == 0)
            _root = node

        if (size > 2) {
            node.putLeft(this.recursiveBuild(list.subList(0, mid), depth + 1)!!) //Recur on sublist of everything before midpoint
            node.putRight(this.recursiveBuild(list.subList(mid + 1, size), depth + 1)!!) //recur on sublist of everything after midpoint
        } else if (size == 2) { //mid must be 1
            if (list[0].compareAxis(list[1], axis) >= 0)
                node.putRight(this.recursiveBuild(list.subList(0, 1), depth + 1)!!) //the node before mid
            else
                node.putLeft(this.recursiveBuild(list.subList(0, 1), depth + 1)!!) //node before mid
        }
        _size++
        return node
    }


    /**
     * This method takes a collection of objects that implement
     * KDimensionable and recursively builds a balanced KD Tree
     * from them.
     *
     * If the KDTree's _k field (number of dimensions) has not been set,
     * Or if the depth (for whatever hellish reason) is negative,
     * Or if the list is empty,
     * an error message will print to STDERROR.
     *
     *
     * @param list - The list of KDimensionable objects
     * @param depth - The depth at which to add the nodes
     */
    fun recursiveBuildFaster(superList: ArrayList<List<KDType>>, depth: Int): KDNode? {
        val size = superList[0].size

        if (numDimensions < 1) {
            System.err.println("ERROR: KDTree.recursiveBuildFaster(): Number of Dimensions has not been defined.")
            return null
        }
        if (depth < 0) {
            System.err.println("ERROR: KDTree.recursiveBuildFaster(): Cannot build tree from a negative depth!")
            return null
        }
        if (size == 0) {
            System.err.println("ERROR: KDTree.recursiveBuildfaster(): Cannot build tree from an empty list.")
            return null
        }

        val axis = depth % numDimensions    //the 'axis' is the dimension that the nodes should be compared by.
        //it is determined by the current depth

        //split list by median
        val median: KDType
        val mid = size / 2 //floor of size/2
        median = superList[axis][mid] //get median object from desired axis-sorted list in superList

        //create node, split list around median and recur
        //if there is only one node left in the list, it's our median,
        //so we're done with building the tree and we can return the
        //last node which we just created from the median.
        val node = KDNode(median)
        if (depth == 0) _root = node //set node to root if it's the first one

        //create new sets of branches, split around the median object.
        var branches: Branches? = Branches(superList, mid, axis)
        val less = branches!!.less //all object less than or equal to (on current axis)
        val more = branches.more //all objects greater than (on current axis)

        if (!less[0].isEmpty())
            node.putLeft(this.recursiveBuildFaster(less, depth + 1)!!)
        if (!more[0].isEmpty())
            node.putRight(this.recursiveBuildFaster(more, depth + 1)!!)
        //XXX to save memory.
        branches = null

        _size++
        return node
    }

    /**
     * Searches this tree for at most n nearest neighbors
     * to the given point, and returns a list of nearest-neighbor
     * KDimensionable objects in a list,
     * sorted nearest to farthest
     *
     * @param n - the number of neighbors to return in the list
     * @param testPoint - the test point from which neighbors are compared/found
     * @return a list of (at most) n KDimensional objects, in ascending order
     * by distance to the test point.
     */
    fun getNearestNeighbors(n: Int, testPoint: KDimensionable): List<KDType>? {
        if (_root == null) {
            System.err.println("ERROR: KDTree.getNearestNeighbors(): Tree has not been constructed.")
            return null
        }
        if (n < 0) {
            System.err.println("ERROR: KDTree.getNearestNeighbors(): Cannot search negative number of neighbors.")
            return null
        } else if (n == 0) {
            return ArrayList(0)
        }

        _neighborList = NeighborList(n, testPoint)
        this.recursiveNeighborSearch(_root, 0)

        val l = _neighborList!!.asList() //sorts the list for you
        _neighborList!!.clear() //dont need it anymore; clear it out to be safe.
        return l //returns a sorted list
    }

    /**
     * Recursive nearest neighbor search.<br></br>
     * Searches for nearest neighbors according to the supplied neighbor list,
     * inserting objects it finds along the way. The NeighborList class
     * takes care of deciding whether or not the object should actually be added
     * to the neighbor list.
     *
     * @param currNode - a node holding a candidate for nearest neighbor,
     * whose subtrees this algorithm will search.
     * @param depth - the current depth of this search in the tree. root = depth 0.
     * @param neighbors - the list of neighbors to pass around, stores the test point.
     * @return
     * A list of nearest neighbors, sorted in ascending order by distance to
     * the test point and  bound to a specific quantity.
     */
     fun recursiveNeighborSearch(currNode: KDNode?, depth: Int) {
        if (currNode == null) return
        val p = _neighborList!!.testPoint
        val curr = currNode.kdObject
        if (!curr.equals(p)) {
            _neighborList!!.insert(curr) //curr will not be inserted if List is at max and curr is worse than the worst
        }

        //recursively search the subtree which contains the test point.
        var wentLeft = false
        val axis = depth % numDimensions
        if (p.compareAxis(curr, axis) <= 0) {
            this.recursiveNeighborSearch(currNode.left, depth + 1)
            wentLeft = true
        } else {
            this.recursiveNeighborSearch(currNode.right, depth + 1)
        }

        //search other subtree if not enough neighbors or distance to test point on axis is less than worst
        //distance of neighborList (axes could be equal)
        val axisDiff = Math.abs(curr.coordinates[axis] - p.coordinates[axis])
        val worstDist = _neighborList!!.worstDist
        if (!_neighborList!!.isFull || axisDiff < worstDist) {
            //search the subtree we haven't yet searched using the (wentLeft flag)
            if (wentLeft)
                this.recursiveNeighborSearch(currNode.right, depth + 1)
            else
                this.recursiveNeighborSearch(currNode.left, depth + 1)
        }
    }


    /**
     * Returns all KDimensionable objects in this tree in a sorted list.
     * The list is sorted in ascending order by distance from the testPoint.
     *
     * @param radiusSquared - the length of the radius to search.
     * @param testPoint - the point from which to define the radius.
     * @return
     * a list of KDimensionable objects in ascending order by distance to the testpoint.
     */
    fun getObjectsWithinRadius(radiusSquared: Double, testPoint: KDimensionable): List<KDType>? {
        if (_root == null) {
            System.err.println("ERROR: KDTree.getObjectsWithinRadius(): Tree has not been constructed.")
            return null
        }
        if (radiusSquared <= 0) {
            System.err.println("ERROR: KDTree.getObjectsWithinRadius(): Cannot search a non-positive radius.")
            return null
        }

        val points = ArrayList<KDType>()
        points.addAll(this.recursiveRadiusSearch(_root, 0, radiusSquared, testPoint))
        Collections.sort(points, DistanceToPointComparator(testPoint)) //sort according to distance to the test point
        return points
    }

    /**
     * Recursive radius search.<br></br>
     * Searches the tree starting with currNode and descending
     * into the left and/or right subtrees as necessary,
     * maintaining a list of KDimensionables within the radius.
     *
     * @param currNode - the current node that the recursive search is looking at.
     * @param depth - the depth of the current node. root depth = 0.
     * @param radius - the length of the radius to search
     * @param testPoint - the point from which the radius is defined.
     * @return
     * A collection of KDimensionable object that are contained in
     * currNode's subtrees (in no particular order).
     */
     fun recursiveRadiusSearch(currNode: KDNode?, depth: Int, radius: Double, testPoint: KDimensionable): Collection<KDType> {
        val points = ArrayList<KDType>()
        if (currNode == null)
            return points

        val curr = currNode.kdObject
        val currDist = curr.distanceTo(testPoint)
        if (currDist < radius) {
            //if curr is within radius, add it and search subtrees.
            if (!curr.equals(testPoint)) {
                points.add(curr)
            }
            points.addAll(this.recursiveRadiusSearch(currNode.left, depth + 1, radius, testPoint))
            points.addAll(this.recursiveRadiusSearch(currNode.right, depth + 1, radius, testPoint))
        } else {
            //curr is not within radius.
            val axis = depth % numDimensions
            val axisDiff = Math.abs(curr.coordinates[axis] - testPoint.coordinates[axis])
            if (axisDiff < radius) { //if axis Differential is less than radius, search both subtrees for candidates
                points.addAll(this.recursiveRadiusSearch(currNode.left, depth + 1, radius, testPoint))
                points.addAll(this.recursiveRadiusSearch(currNode.right, depth + 1, radius, testPoint))
            } else {
                //axis Differential is larger than radius. Move towards test point in search.
                if (curr.coordinates[axis] <= testPoint.coordinates[axis]) {
                    //axis of curr is less than or equal to test point : go right
                    points.addAll(this.recursiveRadiusSearch(currNode.right, depth + 1, radius, testPoint))
                } else {
                    //axis of curr is greater than test point, go left.
                    points.addAll(this.recursiveRadiusSearch(currNode.left, depth + 1, radius, testPoint))
                }
            }
        }

        return points //return candidates.
    }

    /**
     * Tests whether or not this tree contains a specific KDType object.
     * This method is only used for testing.
     *
     * @param kd the KDimensional object to find.
     * @return
     * True if the KDimensionable object is in the tree, false otherwise.
     */
    operator fun contains(kd: KDType): Boolean {
        if (_root == null || numDimensions < 1) {
            System.err.println("ERROR: KDTree.contains(): Tree is not defined.")
            return false
        }
        var curr = _root
        var axis: Int
        var depth = 0
        while (curr != null) {
            axis = depth % numDimensions
            val o = curr.kdObject
            val result = kd.compareAxis(o, axis)
            if (result > 0) {
                curr = curr.right
            } else if (result < 0) {
                curr = curr.left
            } else {
                if (kd.equals(o))
                    return true
                else
                    curr = curr.left
            }
            depth++

        }
        return false
    }


    /**
     * Private method only used for subtree testing.
     * Returns the Node at which the specified KDimensionable object an be found,
     * that is, if the object is found in the tree.
     * @param kd
     * @return
     */
     fun find(kd: KDType): KDNode? {
        if (_root == null || numDimensions < 1) {
            System.err.println("ERROR: KDTree.find(): Tree is not defined.")
            return null
        }
        var curr = _root
        var axis: Int
        val depth = 0
        while (curr != null) {
            axis = depth % numDimensions
            val o = curr.kdObject
            val result = kd.compareAxis(o, axis)
            if (result > 0) {
                curr = curr.right
            } else if (result < 0) {
                curr = curr.left
            } else {
                if (kd.equals(o))
                    return curr
                else
                    curr = curr.right
            }
        }
        return null //object not found

    }

    fun size(): Long {
        return _size
    }


    /**
     * A helper class that splits the 'list of lists'
     * into lists of lesser and greater. Used to build the tree so
     * that the list of nodes only has to be sorted 3 times,
     * (in the beginning- in the constructor).
     *
     * @author emc3 / skortchm
     */
     inner class Branches
    //lesser & greater based on the object at the median index.

    internal constructor(superList: ArrayList<List<KDType>>, medianIndex: Int, axis: Int) {

         val less: ArrayList<List<KDType>>
         val more: ArrayList<List<KDType>> //each instance of Branches will be split into

        init {
            val medianVal = superList[axis][medianIndex] //get median object

            //The length of sublist: the number of KDTypes.
            val listSize = superList[0].size

            //Initializing less and more superLists.
            less = ArrayList(numDimensions)
            more = ArrayList(numDimensions)

            for (i in 0 until numDimensions) {
                //The sublists will be approximately half of the size of the initial, which is ~ the same as the median index.
                val tempLessList = ArrayList<KDType>(medianIndex)
                //Less list will always have fewer elements, because it also has to handle =
                val tempMoreList = ArrayList<KDType>(if (medianIndex % 2 == 0) medianIndex else medianIndex + 1)

                //We iterate through each sorted list, distributing elements to
                //less and more based on comparison to the splitting pane. make sure to not add the median value to to either list.
                //loop through all elements in list
                for (j in 0 until listSize) {
                    val temp = superList[i][j] //get the object in the list
                    val cmp = temp.compareAxis(medianVal, axis) //compare object to median object

                    if (cmp > 0)
                        tempMoreList.add(temp)
                    else if (cmp < 0)
                        tempLessList.add(temp)
                    else if (cmp == 0 && !temp.equals(medianVal))
                        tempLessList.add(temp) //in case of same axis but not same object, add object to less list.
                }
                less.add(tempLessList)
                more.add(tempMoreList)
            }
        }
    }


    /**
     * This inner class represents a KDTree node.
     * It can hold anything that implements KDimensionable,
     * which is an Interface supplied with this package.
     * @author emc3
     */
     inner class KDNode
    /**
     * Constructor for a KDNode.<br></br>
     * Initializes left & right children to null
     * to signify 'no children'.
     * @param o -	An object which implements KDimensionable, to be stored as
     * the value for this node.
     */
     constructor(
            /**
             * Returns the object stored at this node.<br></br>
             * The object can be anything that implements KDimensionable.
             *
             * @return The object stored at this node.
             */
            val kdObject: KDType //the object which implements KDimensionable
    ) {
        /**
         * @return the left child of this node if one exists.
         * If no left child exists, this method will return null.
         */
        public var left: KDNode? = null
        /**
         * @return the right child of this node if one exists.
         * If no left child exists, this method will return null.
         */
        public var right: KDNode? = null //the left and right children of this node


        init {
            left = null
            right = null
        }


        /**
         * Give this node a left child.
         *
         * @param node -	the node to set as this node's left child.
         */
         fun putLeft(node: KDNode) {
            left = node
        }


        /**
         * Give this node a right child.
         *
         * @param node -	the node to set as this node's right child.
         */
         fun putRight(node: KDNode) {
            right = node
        }
    }

     inner class MinMaxPair internal constructor(internal var min: Double, internal var max: Double)


    /**
     * This inner class represents a
     * Bounded-priority queue which holds KDimensionable
     * objects. The objects are sorted by their distance
     * to a fixed test point, supplied on construction of
     * the list (the distance of the object to the test
     * point is its priority in the queue).
     *
     * @author emc3
     */
     inner class NeighborList
    /**
     * Default constructor<br></br>
     * Creates a new Nearest-Neighbor, which ranks nodes
     * in ascending order by distance to the test point.
     *
     *
     * The test point is specified by the KDimensionable object.
     * The list is bound to n members.
     *
     * @param n        - The number of neighbors that this list holds. The list will never outgrow n.
     * @param point    - The test point; neighbors will be compared by their distance to this point.
     */
     constructor( val _n: Int //the number of neighbors to keep in the list.
                        ,
                        /**
                         * @return
                         * The test point which is used to sort the list by
                         * objects' distances.
                         */
                        val testPoint: KDimensionable //the fixed point to compare all neighbors to
    ) : Comparator<KDType> {
         var _neighbors: ArrayList<KDType>? = null //the list of neighbors
         var _worst: KDType? = null    //the object with the worst distance to the test point
        /**
         * @return
         * the 'worst' KDimensionable object in the list.<br></br>
         * i.e. the coordinates with the greatest distance to
         * the test point.
         */
         var worstDist: Double = 0.toDouble()

        /**
         * returns true if this List is at capacity n
         * @return true if List at capacity, false otherwise
         */
         val isFull: Boolean
            get() = if (_neighbors!!.size == _n) true else false

        init {
            _neighbors = ArrayList(_n)
            _worst = null
            worstDist = java.lang.Double.POSITIVE_INFINITY
        }

        /**
         * Inserts a KDimensionable object to the nearest neighbor list,
         * and sorts the list by distance to the test point.
         *
         *
         * If this list is at capacity (size = n),
         * the incoming KDimensional object is compared to the 'worst' object in the list,
         * i.e. the item in the list which is farthest from the test point.
         * If the incoming object is better than the worst, the incoming object is
         * added to the list and the list is re-sorted.<br></br>
         * If the incoming object is worse than the worst, it is thrown out.
         *
         * @param kd - the incoming object to insert into the list, provided that it
         * is better than current worst item in the list.
         */
        fun insert(kd: KDType) {
            val dist = kd.distanceTo(testPoint)
            if (_neighbors!!.size < _n) { //if the list is not at capacity, add the neighbor.
                if (dist > worstDist) { //if it's the new worst neighbor, grab it
                    _worst = kd
                    worstDist = dist
                }
                _neighbors!!.add(kd) //add the new nieghbor to the list.
            } else if (dist < worstDist) { //if the list is at capacity, remove worst, add new, determine new worst.
                _neighbors!!.add(kd) //add new neighbor
                Collections.sort(_neighbors!!, this) // sort the list by distance to test point
                _neighbors!!.removeAt(_neighbors!!.size - 1) //never going to remove kd because we already determined its closer than the worst.
                _worst = _neighbors!![_neighbors!!.size - 1] //new worst using new size
                worstDist = _worst!!.distanceTo(testPoint)
            }
        }


        /**
         * @return
         * The list of nearest neighbors.
         * Size of list is bound by n, the integer
         * which was specified to this list on construction.
         */
         fun asList(): List<KDType> {
            Collections.sort(_neighbors!!, this)
            return _neighbors as ArrayList<KDType>
        }

        /**
         * @return the number of neighbors currently in the list
         */
         fun size(): Int {
            return _neighbors!!.size
        }

         fun clear() {
            _neighbors = null
            _worst = null
            worstDist = java.lang.Double.POSITIVE_INFINITY
        }

        /**
         * Compares KDimensionable objects based on their distance to the input point.
         * This will order the list so that objects closer to the input point
         * will come first in the list and objects that are farther away will
         * be at the end of the list.
         *
         * @return    -1 if the first object is closer to the input point
         * 0 if the objects are the same distance to the input point
         * 1 if the first object is farther away form the input point.
         */
        override fun compare(o1: KDType, o2: KDType): Int {
            val d1 = o1.distanceTo(testPoint)
            val d2 = o2.distanceTo(testPoint)
            if (d1 < d2) {
                return -1
            } else if (d1 > d2) {
                return 1
            }
            return 0
        }

    }

    /**
     * This inner class represents a comparator used to sort
     * KDimensionable objects in a list according to a given test point.
     *
     *
     * This class is employed by the radius search, in order to
     * return a list of KDimensionable objects within a radius
     * to a given point, p, where the list is sorted by the objects'
     * distance to that point, in ascending order.
     *
     * @author emc3
     */
    inner class DistanceToPointComparator
    /**
     * Default constructor. Initializes the Test point
     * to use for this comparator.
     *
     * @param p the test point to use for this comparator.
     */
    constructor( val _p: KDimensionable //the test point
    ) : Comparator<KDType> {


        /**
         * Compares 2 points based on their distance to the test point, _p,
         * specified in the constructor.
         *
         * @return
         * -1 if the first object is closer to the test point than the second<br></br>
         * 0 if the two objects are equal distance from the test point<br></br>
         * 1 if the first object is farther from the test point than the second object.
         */
        override fun compare(o1: KDType, o2: KDType): Int {
            val d1 = o1.distanceTo(_p)
            val d2 = o2.distanceTo(_p)

            if (d1 < d2)
                return -1
            else if (d1 > d2)
                return 1
            return 0
        }

    }
}

interface KDimensionable {


    /**
     * @return an array of the coordinates of a point
     * in a k-dimensional space.<br></br>
     * For example, if the point is specified by 3-Dimensions,
     * the array will be of size 3, and ordered as {x, y, z}.
     */
    var coordinates: DoubleArray


    /**
     * @return
     * the number of dimensions that this
     * KDimensional object represents.<br></br>
     * e.g. for 2D, this method should return 2.
     * for 3D, this method should return 3, and so on.
     */
    val numDimensions: Int


    /**
     * Compares two KDimensionable objects based on a specific axis.
     * This method facilitates the comparing done when building
     * the KDTree.
     * @param kd -	the KDimensionable object to compare with
     * @param axis-	the axis to compare on
     * @return
     *
     *  * 	1 if this object has a larger coordinate compared to the parameter object
     * on the specified axis.
     *  *  0 if the coordinates are equal on the specified axis
     *  *  -1 if this object's coordinate is lesser than the specified object's coordinate
     *
     */
    fun compareAxis(kd: KDimensionable, axis: Int): Int


    /**
     * Calculates the distance between this object and the parameter object.
     * You should check to make sure the two objects have the same number of
     * dimensions, or normalize the missing dimensions to 0.
     *
     * @param kd - a KDimensional object to measure the distance to
     * @return the distance between this object and the specified KDimensionable object
     */
    fun distanceTo(kd: KDimensionable): Double

}


/**
 *
 */


/**
 * KDimensionComparator<br></br>
 * This class represents the comparator used to sort the list of
 * coordinates that the KDTree uses to build itself. Since the KDTree
 * must be balanced to optimize its runtime, it must always choose
 * the median based on which dimension is used at the given level.
 * This class allows the KDTree to call Collections.sort on the list of
 * incoming KDimensionable objects, as to easily grab the median from
 * the list.
 *
 * @author emc3
 */
class KDimensionComparator
/**
 * Default constructor. Requires that the caller
 * specifies an axis which the KDimensionable objects
 * will be compared by. For example, to compare by
 * x-values, axis would be the number 0.
 *
 * @param axis -	the coordinate to compare the KDimensionable
 * objects by.
 */
(axis: Int) : Comparator<KDimensionable> {

     var _axis: Int = 0 //the dimension to compare

    init {
        if (axis >= 0)
            _axis = axis
        else
            System.err.println("ERROR: KDimensionComparator: axis for compare must be non-negative.")
    }


    /**
     * Compares the two given objects based on the
     * axis specified to this object during construction.
     */
    override fun compare(o1: KDimensionable, o2: KDimensionable): Int {
        return o1.compareAxis(o2, _axis)
    }

}

class KDStub(x: Double, y: Double, override var coordinates: DoubleArray, override val numDimensions: Int) : KDimensionable {
    init {
        coordinates = DoubleArray(2)
        coordinates[0] = x
        coordinates[1] = y
    }

    override fun compareAxis(kd: KDimensionable, axis: Int): Int {
        if (axis > 1 || axis < 0) {
            throw IllegalArgumentException(String.format("Axis %d out of range: must be 1 or 0", axis))
        }
        val mine = coordinates[axis]
        val other = kd.coordinates[axis]
        return java.lang.Double.compare(mine, other)
    }

    /**
     * Note this distance is SQUARED
     */
    override fun distanceTo(kd: KDimensionable): Double {
        var dist = 0.0
        if (this.numDimensions != kd.numDimensions) {
            throw IllegalArgumentException("Wrong dimensionality of objects")
        }
        for (i in 0 until numDimensions) {
            dist += Math.pow(coordinates[i] - kd.coordinates[i], 2.0)
        }
        return dist
    }

    companion object {
         val serialVersionUID = 1L
    }

}