How to use the spread operator with ArrayList in kotlin? - kotlin

I've read the documentation and I run into this issue of using the spread operator with an ArrayList Collection, and I want to know how to solve the mismatch type or implement a way to use it with ArrayList
I'll attach an image of the code along with the code.
fun howSum(targetSum: Int, numbers: ArrayList<Int>): ArrayList<Int>? {
if (targetSum == 0) return arrayListOf();
if (targetSum < 0) return null;
for (number: Int in numbers){
val remainder = targetSum - number;
val remainderResult = howSum(remainder, numbers);
if (remainderResult != null){
return arrayListOf(*remainderResult, number)
}
}
return null
}
Any comment could be helpful...

I think you need to give us more information about what you are trying to do for a better answer.
The spread operator is for passing an array in place of a varargs argument, but you can't add additional arguments to the array at the same time.
If you want a new ArrayList that contains the contents of another ArrayList with an extra element added, you can do something like this:
fun main() {
val foo = arrayListOf(1, 2, 3)
val bar = arrayListOf<Int>().apply {
addAll(foo)
add(4)
}
println(foo)
println(bar)
}
Output:
[1, 2, 3]
[1, 2, 3, 4]
But it's not efficient, because it copies all the items of foo into bar.

Spread operator is not applicable to Lists, it's intended only for arrays:
fun howSum(targetSum: Int, numbers: ArrayList<Int>): IntArray? {
if (targetSum == 0) return intArrayOf()
if (targetSum < 0) return null
for (number: Int in numbers) {
val remainder = targetSum - number;
val remainderResult = howSum(remainder, numbers);
if (remainderResult != null) {
return intArrayOf(*remainderResult, number)
}
}
return null
}
If you want to create new List of the other one with addition of some element, you can use + operator:
fun howSum(targetSum: Int, numbers: ArrayList<Int>): List<Int>? {
if (targetSum == 0) return arrayListOf();
if (targetSum < 0) return null;
for (number: Int in numbers){
val remainder = targetSum - number;
val remainderResult = howSum(remainder, numbers);
if (remainderResult != null){
return remainderResult + number
}
}
return null
}

Related

kotlin product of odd or even integers

The problem I'm working on accepts a number string and will output the product of the odd or even numbers in the string. While the product of purely number string is working fine, my code should also accept strings that is alphanumeric (ex: 67shdg8092) and output the product. I'm quite confused on how I should code the alphanumeric strings, because the code I have done uses toInt().
Here's my code:
fun myProd(Odd: Boolean, vararg data: Char): Int {
var bool = isOdd
var EvenProd = 1
var OddProd = 1
for (a in data)
{
val intVal = a.toString().toInt()
if (intVal == 0)
{
continue
}
if (intVal % 2 == 0)
{
EvenProd *= intVal
}
else
{
OddProd *= intVal
}
}
if(bool == true) return OddProd
else return EvenProd
}
Use toIntOrNull instead of toInt. It only converts numeric string
val intVal = a.toString().toIntOrNull()
if (intVal == null || intVal == 0) {
continue
}
Starting from Kotlin 1.6 you can also use a.digitToIntOrNull().
P.S. Your method could be also rewritten in functional style
fun myProd(isOdd: Boolean, input: String): Int {
return input.asSequence()
.mapNotNull { it.toString().toIntOrNull() } // parse to numeric, ignore non-numeric
.filter { it > 0 } // avoid multiplying by zero
.filter { if (isOdd) it % 2 != 0 else it % 2 == 0 } // pick either odd or even numbers
.fold(1) { prod, i -> prod * i } // accumulate with initial 1
}

Kotlin - How to check if a char is present in a matrix?

Only for context: I am trying to implement Playfair Cipher. It would be really helpful if you take a look at Playfair Cipher to understand my problem.
This program is just for some background:
fun main(){
println("Enter the message:")
var message:String = readLine()!!.toUpperCase()
println("Enter the key:")
var key:String = readLine()!!.toUpperCase()
var cipTable = Array(5){ Array(5){'X'}}
var j=0; //to iterate througm my key
for(innerArray in cipTable){
for(i in innerArray.indices){
if(key[j++] !in cipTable)
innerArray[i]+=key[j]
if(j==key.length) break
}
}
}
My main issue is with this part:
for(innerArray in cipTable){
for(i in innerArray.indices){
if(key[j++] !in cipTable)
I wanted to check if the key that I am going to insert in the matrix is already present in it or not. I also cannot use innerArray instead of cipTable as it would only check for char in the same row. Is there any way I can check if a char is present or not in the entire matrix?
For eg.:
fun main(){
var result = arrayOf(
intArrayOf(3, 2, 4),
intArrayOf(6, 7, 9),
intArrayOf(12, 11, 23)
)
//To check if 2 is present in the entire matrix/table
if(result.any { 2 !in it}) println("not present") else print("present")
}
Can you tell me what is wrong in this code because the output is not expected. Also is there any way I can use forEach for the same.
If I understand correctly, you want this for loop to result in a true or false based on whether any inner array has the same sequence and number of chars as the key String.
First of all, the inner array should be a CharArray instead of an Array<Char>, to avoid boxing.
val cipTable = Array(5) { CharArray(5) { 'X' } }
Then you can use all and contentEquals to check if any of the inner CharArrays are a match for the key.
val charArrayKey = key.toCharArray()
val isKeyInTable = cipTable.any { it.contentEquals(charArrayKey) }
If you want to skip the step of converting the key to a CharArray, you can manually check it like this:
val isKeyInTable =
cipTable.any { it.size == key.length && it.withIndex().all { (i, c) -> c == key[i] } }
I guess one way is to use extensions.
fun Array<IntArray>.has(x:Int):Boolean{
for(innerArray in this){
if(x in innerArray)
return true
}
return false
}
fun main(){
var result = arrayOf(
intArrayOf(3, 2, 4),
intArrayOf(6, 7, 9),
intArrayOf(12, 11, 23)
)
//To check if 43 or 4 is present in the entire matrix/table
if(result.has(43)) println("present") else println("not present")
if(result.has(4)) println("present") else println("not present")
}

Kotlin - The caracter literal does not conform expect type Int

I'm struggling with types with my program, I've been asked to do it in JS first and it worked fine but now I can't achieve the result.
Do you think I should make another 'algorithm' ? In advance, thank you for your time.
fun main(){
// the idea is to put numbers in a box
// that cant be larger than 10
val data = "12493419133"
var result = data[0]
var currentBox = Character.getNumericValue(data[0])
var i = 1
while(i < data.length){
val currentArticle = Character.getNumericValue(data[i])
currentBox += currentArticle
println(currentBox)
if(currentBox <= 10){
result += Character.getNumericValue(currentArticle)
}else{
result += '/'
//var resultChar = result.toChar()
// result += '/'
currentBox = Character.getNumericValue(currentArticle)
result += currentArticle
}
i++
}
print(result) //should print 124/9/341/91/33
}
The result is actually of a Char type, and the overload operator function + only accepts Int to increment ASCII value to get new Char.
public operator fun plus(other: Int): Char
In idomatic Kotlin way, you can solve your problem:
fun main() {
val data = "12493419133"
var counter = 0
val result = data.asSequence()
.map(Character::getNumericValue)
.map { c ->
counter += c
if (counter <= 10) c.toString() else "/$c".also{ counter = c }
}
.joinToString("") // terminal operation, will trigger the map functions
println(result)
}
Edit: If the data is too large, you may want to use StringBuilder because it doesn't create string every single time the character is iterated, and instead of using a counter of yourself you can use list.fold()
fun main() {
val data = "12493419133"
val sb = StringBuilder()
data.fold(0) { acc, c ->
val num = Character.getNumericValue(c)
val count = num + acc
val ret = if (count > 10) num.also { sb.append('/') } else count
ret.also { sb.append(c) } // `ret` returned to ^fold, next time will be passed as acc
}
println(sb.toString())
}
If you want a result in List<Char> type:
val data = "12493419133"
val result = mutableListOf<Char>()
var sum = 0
data.asSequence().forEach {
val v = Character.getNumericValue(it)
sum += v
if (sum > 10) {
result.add('/')
sum = v
}
result.add(it)
}
println(result.joinToString(""))

Kotlin decomposing numbers into powers of 2

Hi I am writing an app in kotlin and need to decompose a number into powers of 2.
I have already done this in c#, PHP and swift but kotlin works differently somehow.
having researched this I believe it is something to do with the numbers in my code going negative somewhere and that the solution lies in declaring one or more of the variable as "Long" to prevent this from happening but i have not been able to figure out how to do this.
here is my code:
var salads = StringBuilder()
var value = 127
var j=0
while (j < 256) {
var mask = 1 shl j
if(value != 0 && mask != 0) {
salads.append(mask)
salads.append(",")
}
j += 1
}
// salads = (salads.dropLast()) // removes the final ","
println("Salads = $salads")
This shoud output the following:
1,2,4,8,16,32,64
What I actually get is:
1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,
Any ideas?
This works for the one input that you specified, at the very least:
fun powersOfTwo(value :Long): String {
val result = ArrayList<String>()
var i = 0
var lastMask = 0
while (lastMask < value) {
val mask = 1 shl i
if (value != 0.toLong() && mask < value) {
result.add(mask.toString())
}
lastMask = mask
i += 1
}
return result.joinToString(",")
}
Ran it in a unit test:
#Test
fun addition_isCorrect() {
val result = powersOfTwo(127)
assertEquals("1,2,4,8,16,32,64", result)
}
Test passed.
You can get a list of all powers of two that fit in Int and test each of them for whether the value contains it with the infix function and:
val value = 126
val powersOfTwo = (0 until Int.SIZE_BITS).map { n -> 1 shl n }
println(powersOfTwo.filter { p -> value and p != 0}.joinToString(","))
// prints: 2,4,8,16,32,64
See the entire code in Kotlin playground: https://pl.kotl.in/f4CZtmCyI
Hi I finally managed to get this working properly:
fun decomposeByTwo(value :Int): String {
val result = ArrayList<String>()
var value = value
var j = 0
while (j < 256) {
var mask = 1 shl j
if ((value and mask) != 0) {
value -= mask
result.add(mask.toString())
}
j += 1
}
return result.toString()
}
I hope this helps someone trying to get a handle on bitwise options!
Somehow you want to do the "bitwise AND" of "value" and "mask" to determine if the j-th bit of "value" is set. I think you just forgot that test in your kotlin implementation.

Assigning values to ArrayList using mapTo

Previously I was using this code:
private val mItems = ArrayList<Int>()
(1..item_count).mapTo(mItems) { it }
/*
mItems will be: "1, 2, 3, 4, 5, ..., item_count"
*/
Now, I am using a class instead of Int, but the class has Int member with name id.
class ModelClass(var id: Int = 0, var status: String = "smth")
So how can I use this method to fill the ArrayList in similar way?
//?
private val mItems = ArrayList<ModelClass>()
(1..item_count).mapTo(mItems) { mItems[position].id = it } // Something like this
//?
From the mapTo documentation:
Applies the given transform function to each element of the original collection and appends the results to the given destination.
Therefore, you just need to return the elements you want:
(1..item_count).mapTo(mItems) { ModelClass(it) }
If you are OK with any MutableList (which is often ArrayList or similar):
val mItems1 = MutableList(item_count) { i -> i }
val mItems2 = MutableList(item_count) { ModelClass(it) }