Loop String from Console and sum odd numbers - kotlin

fun main(args: Array<String>) {
println("Number: ")
val num = readLine()!!.toInt()
var sum = 0
for (digit in num) {
if (digit % 2 != 0) {
sum += digit
}
}
println("$sum")
}
I need this loop to go through every digit in the number and sums all the digits that are odd.
It gives me an error on num "For-loop range must have an 'iterator()' method"

You cannot iterate over an Int like num:
val num = readLine()!!.toInt()
You can fix it without a loop and by using standard functions map, filter and sum:
val sum = readLine()!!.toCharArray()
.map { it.toString().toInt() }
.filter { it % 2 != 0 }
.sum()
The filter-condition for even numbers would be it % 2 == 0
EDIT
For your homework, do this:
val num = readLine()!!.toCharArray()
var sum = 0
for (a in num) {
val intVal = a.toString().toInt()
if (intVal % 2 != 0) {
sum += intVal
}
}

Related

I can't figure out how to get the largest element in loop

I don't understand the loop in the following content.
There is a sequence of integer numbers (which ends with the number 0). Find the largest element of this sequence.
The number 0 itself is not included in the sequence. It serves only as a sign that there are no more numbers.
I tried various methods, but they did not solve the problem.
The way to exit the loop at 0 is to use
While(i ! = 0){}
Here is the code we created.
fun main(args: Array<String>) {
val scanner = Scanner(System.`in`)
var count = scanner.nextInt()
do {
var input = scanner.nextInt()
while(input != 0 || count != 0) {
if (count < input){
count = input
}
}
}while(input != 0 || count != 0)
println(count)
}
You can use maxOf() for example:
fun readLn() = readLine()!!
fun readIntOrStopLoopWithZero() = readLn().toIntOrNull() ?: 0
fun readMaxInteger() {
var maxInput: Int = 0
//getting first user input
var userInput = readIntOrStopLoopWithZero()
while (userInput!= 0) {
//calc max
maxInput = maxOf(userInput, maxInput)
//getting user input again.
userInput= readIntOrStopLoopWithZero()
}
if (maxInput == 0)
//In case we get 0 as first input.
print("max value not found")
else
print("Max input is : $maxInput")
}
readMaxInteger()
Input:
1
2
0
output:
Max input is 2
Input:
1
0
output:
Max input is 1
Input:
0
output:
max value not found
Input:
1
2
3
Word
output:
Max input is : 3
Problems:
You've over-complicated it by creating a nested loop.
You're checking input != 0 to exit either of the loops, so it will exit immediately on the first element.
So fixing these problems, you have:
fun main(args: Array<String>) {
val scanner = Scanner(System.`in`)
var count = 0 // start with 0 for simplicity
do {
val input = scanner.nextInt()
if (count < input) {
count = input
}
} while (input != 0)
println(count)
}
And here's an alternate solution. Make a Sequence so it becomes an Iterable and you can use maxOrNull() on it:
fun main(args: Array<String>) {
val sequence = sequence {
val scanner = Scanner(System.`in`)
do {
val input = scanner.nextInt()
yield(input)
} while (input != 0)
}
println(sequence.maxOrNull() ?: 0)
}
I wanted to finish within a single function, so I chose the following.
fun main(args: Array<String>) {
val scanner = Scanner(System.`in`)
var count = 0 // start with 0 for simplicity
do {
val input = scanner.nextInt()
if (count < input) {
count = input
}
} while (input != 0)
println(count)
}
Thanks to everyone who responded!

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("")
}
}
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:
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.
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

Ranges in Kotlin

How do I write code to return a range of 10 numbers from a given number.
i.e if I am given 5, code should return 0..9
358 should return 350..359
33 should return 30..39 etc
Do you mean something like this?
fun range10(contained: Int): IntRange {
val start = contained - contained % 10
val end = start + 9
return start..end
}
If the given number is integer type, you can simply write
val x = 358
(x / 10 * 10)..(x / 10 * 10 + 9)
You can use the following code:
fun answer(givenNum: Int) : IntRange {
val startOfRange = givenNum - (givenNum % 10)
return startOfRange until (startOfRange + 10)
}
fun main() {
val givenNum = 33
println(answer(givenNum)) // 30..39
}

How do I get the sums for all elements of two lists in Kotlin?

In Kotlin I have two lists:
val x: List<Int> = listOf(1,2,3,4,5,6)
val y: List<Int> = listOf(2,3,4,5,6,7)
How do I get:
val z: List<Int> = 3,5,7,9,11,13
without using loops?
Assuming both list have the same size:
Using zip
val sum = x.zip(y) { xv, yv -> xv + yv }
Using simple map and mapIndexed
val sum = (0 until x.size).map { x[it] + y[it] }
// or
val sum = x.mapIndexed { index, xv -> xv + y[index] }
When the size can be different and you would assume 0 for out of range entries:
Using an array
val sum = IntArray(maxOf(x.size, y.size)) {
x.getOrElse(it, {0}) + y.getOrElse(it, {0})
}.toList()
Using range:
val sum = (0 until maxOf(x.size, y.size)).map {
x.getOrElse(it, {0}) + y.getOrElse(it, {0})
}
Extending the lists to same size
val xExtended = x + Array(maxOf(0, y.size - x.size), { 0 })
val yExtended = y + Array(maxOf(0, x.size - y.size), { 0 })
val sum = xExtended.zip(yExtended) { xv, yv -> xv + yv }
I'd go with a range and map:
val sums = (0 until x.size).map { x[it] + y[it] }
It's probably less overhead than zip.

Sum a subset of of numbers in a list

Is there a way in Kotlin for doing the sum() operation on a filtered list of numbers, without actually filtering out the elements first?
I'm looking for something like this:
val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sum(it > 0)
You can make use of Iterable<T>.sumBy:
/**
* Returns the sum of all values produced by [selector] function applied to each element in the collection.
*/
public inline fun <T> Iterable<T>.sumBy(selector: (T) -> Int): Int {
var sum: Int = 0
for (element in this) {
sum += selector(element)
}
return sum
}
You can pass a function to it where the function transforms negative value to 0. So, it sums up all values in the list which is greater than 0 since adding 0 makes no effect to the result.
val nums = listOf<Long>(-2, -1, 1, 2, 3, 4)
val sum = nums.sumBy { if (it > 0) it.toInt() else 0 }
println(sum) //10
If you require a Long value back, you have to write an extension for Long just like Iterable<T>.sumByDouble.
inline fun <T> Iterable<T>.sumByLong(selector: (T) -> Long): Long {
var sum: Long = 0
for (element in this) {
sum += selector(element)
}
return sum
}
Then, the toInt() conversion can be taken away.
nums.sumByLong { if (it > 0) it else 0 }
As suggested by #Ruckus T-Boom, if (it > 0) it else 0 can be simplified using Long.coerceAtLeast() which returns the value itself or the given minimum value:
nums.sumByLong { it.coerceAtLeast(0) }
sumBy and sumByDouble are Deprecated from kotlin 1.5 . You can check those link.
Use sumOf to get sum on a List or Array
sumOf
Returns the sum of all values produced by selector function applied to each element in the collection or Array.
Example:
data class Order(
val id : String,
val price : Double
)
val orderList = ......
val sum = orderList.sumOf { it.price }
data class Product(val name: String, val quantity: Int) {
}
fun main(args: Array<String>) {
val productList = listOf(
Product("A", 100),
Product("B", 200),
Product("C", 300)
)
val totalPriceInList1: Int = productList.map { it.quantity }.sum()
println("sum(): " + totalPriceInList1)
val totalPriceInList2: Int = productList.sumBy { it.quantity }
println("sumBy(): " + totalPriceInList2)
}
this is the result of our code
sum(): 600
sumBy(): 600