AdamHurwitz
AdamHurwitz

Reputation: 10364

Kotlin Integer.MAX_VALUE Returns Negative Number

Expected

Use Integer.MAX_VALUE in order to consistently return a large number for the purposes of comparison.

Observed

Integer.MAX_VALUE is returning a negative number.

Implement

In the sample code values are saved into a 2D table in order to find the minimum amount of coins required to make up a given amount.

Using Integer.MAX_VALUE

-2147483647 is being derived from Integer.MAX_VALUE.

fun main() {
// Steps - Iterative/bottom-up
//     1. Create a 2D table: Rows = Denominations(Denoms), Columns = Amount(Amt)
//     2. Store min # of coins in at [R][C] = Min(currentDenomMin, previousDenomMin)
//         a. currentDenomMin = [R][C - coins.get(R)] + 1
//         b. previousDenomMin = [R - 1][C]
//     3. Return minCount or -1 for table[coins.size - 1, Amt].
    println("Min count: ${coinChange(intArrayOf(2), 3)}")
}

lateinit var table: Array<IntArray>
lateinit var mCoins: IntArray
private val maxValue = Integer.MAX_VALUE
fun coinChange(coins: IntArray, amt: Int): Int {
    table = Array(coins.size, { IntArray(amt + 1) })
    mCoins = coins
    coins.sort()
    buildMinCounts(amt)
    val minCount = table[coins.size - 1][amt]
    return if (minCount == maxValue) -1 else minCount

}

fun buildMinCounts(amt: Int) {
    for (r in 0..mCoins.size - 1) {
        for (c in 0..amt) {
            val currentDenomValue = mCoins.get(r)
            val currentDenomMin = getDenomMin(r, c - currentDenomValue) + 1
            val previousDenomMin = getDenomMin(r - 1, c)
            if (c == 0) {
                table[r][c] = 0
            } else table[r][c] = Math.min(currentDenomMin, previousDenomMin)
        }
    }
}

fun getDenomMin(r: Int, c: Int): Int {
    if (r < 0 || c < 0) return maxValue
    else return table[r][c]
}

fun printT(amt: Int) {
    for (r in 0..mCoins.size - 1) {
        for (c in 0..amt) {
            print("${table[r][c]} ")
        }
        println("")
    }
}

Using 999999999 as the maxValue instead

Works as expected.

fun main() {
    println("Min count: ${coinChange(intArrayOf(2), 3)}")
}

lateinit var table: Array<IntArray>
lateinit var mCoins: IntArray
private val maxValue = 999999999
fun coinChange(coins: IntArray, amt: Int): Int {
    table = Array(coins.size, { IntArray(amt + 1) })
    mCoins = coins
    coins.sort()
    buildMinCounts(amt)
    val minCount = table[coins.size - 1][amt]
    return if (minCount == maxValue) -1 else minCount

}

fun buildMinCounts(amt: Int) {
    for (r in 0..mCoins.size - 1) {
        for (c in 0..amt) {
            val currentDenomValue = mCoins.get(r)
            val currentDenomMin = getDenomMin(r, c - currentDenomValue) + 1
            val previousDenomMin = getDenomMin(r - 1, c)
            if (c == 0) {
                table[r][c] = 0
            } else table[r][c] = Math.min(currentDenomMin, previousDenomMin)
        }
    }
}

fun getDenomMin(r: Int, c: Int): Int {
    if (r < 0 || c < 0) return maxValue
    else return table[r][c]
}

fun printT(amt: Int) {
    for (r in 0..mCoins.size - 1) {
        for (c in 0..amt) {
            print("${table[r][c]} ")
        }
        println("")
    }
}

Upvotes: 2

Views: 1642

Answers (1)

Dushyant Singh
Dushyant Singh

Reputation: 1577

It's because of overflow. getDenomMin(r, c - currentDenomValue) + 1 returns Integer.MAX_VALUE + 1 which causes overflow. There are two ways to avoid this:

  1. Change maxValue to something such that it doesn't overflows and is actually is the maximum. For example, you have array of size 10^5 containing integers between 1 and 10^9. Now maximum possible sum will 10^5 * 10^9 which is 10^14 so we can set maxValue to any value greater than or equal to 10^14. In your case you can set it to something like 10^5 because you need count not sum which can be at max number of coins available.

  2. val currentDenomMin = getDenomMin(r, c - currentDenomValue) + 1 Before adding 1 you can type it to Long so that it doesn't overflow. val currentDenomMin = getDenomMin(r, c - currentDenomValue).toLong + 1

Upvotes: 3

Related Questions