kotlin-coding-challenges icon indicating copy to clipboard operation
kotlin-coding-challenges copied to clipboard

AnyCallback is a rewrite of an existing Kotlin stdlib function

Open apatrida opened this issue 2 years ago • 0 comments

This question needs redesigned as it enters the realm of "silly" when you can solve this in 1 line of code using first(predicate), none, any, find(predicate), etc. You'd have to list all functions they could not call to make them really want to recurse. If you want a recursive question, then force it with a custom data structure (NodeLinkedList) that doesn't have 10 existing methods that already do the same answer.

If you don't use a custom data structure, the silly factor is that people know they can just call:

return list.any { callback(it) }

Also, the existing Solution1 throws an exception on empty list. Probably not intended but also is not documented?

private object Solution1 {
    private fun anyCallback(list: List<Int>, callback: (Int) -> Boolean): Boolean {
        if (list.size == 1) {
            return callback(list.first())
        }

        // THROWS EXCEPTION ON EMPTY LIST!!!!
        return callback(list.first()) || anyCallback(list.drop(1), callback)
    }
}

the solution could be a little more efficient (don't copy the list, copy a view of the list instead):

internal object Solution2 {
    fun anyCallback(list: List<Int>, callback: (Int) -> Boolean): Boolean {
        if (list.isEmpty()) return false
        return callback(list.first()) || anyCallback(list.subList(1, list.size), callback)
    }
}

Of course that assumes it isn't a LinkedList, but there is always:

internal object Solution3 {
    fun anyCallback(list: List<Int>, callback: (Int) -> Boolean): Boolean {
        fun _randomAccessOptimized(list: List<Int>, callback: (Int) -> Boolean): Boolean {
            if (list.isEmpty()) return false
            return callback(list.first()) || _randomAccessOptimized(list.subList(1, list.size), callback)
        }

        fun _sequentialOptimized(list: List<Int>, callback: (Int) -> Boolean): Boolean {
            if (list.isEmpty()) return false
            return callback(list.first()) || _sequentialOptimized(list.drop(1), callback)
        }


        return if (list is RandomAccess) {
           _randomAccessOptimized(list, callback)
        }
        else {
            _sequentialOptimized(list, callback)
        }
    }
}

apatrida avatar Jul 30 '23 21:07 apatrida