Get values from each string using Kotlin [closed] - kotlin

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 days ago.
Improve this question
I'm new in kotlin, i need to get each integer value and print it.
"""
int a = 5;
int b = 2;
"""
How I can do this?
Thanks!

val input = """
int a = 5;
int b = 2;
"""
val regex = "\\s*int a = (\\d+);\\s*int b = (\\d+);\s*".toRegex()
val result = regex.find(input)
if (result != null) {
val (_, a, b) = result.groupValues
println("a is: $a")
println("b is: $b")
} else {
println("invalid input")
}

Welcome to Kotlin! To achieve the same result as your provided code snippet in Kotlin, you can use the following:
fun main(){
val a: Int = 5
val b: Int = 2
println(a)
println(b)
}
This declares two variables a and b of type Int, assigns them values of 5 and 2 respectively, and then prints their values to the console using the println function. Happy coding!

If by the word "get" you meaning retrieving integers from this string with assignments, there your "parsing":
fun main() {
val codeInString = """
int a = 5;
int b = 2;
"""
codeInString
.lineSequence()
.mapNotNull(::intValueFromAssignmentLine)
.toList()
.let { println("assigned ints: $it") } // assigned ints: [5, 2]
}
fun intValueFromAssignmentLine(line: String) = line
.split('=')
.getOrNull(1) // if there will be no lines without '=', then you don't "OrNull" part here
?.ifEmpty { null } // and `ifEmpty` function here
?.dropLast(1) // drop ';'
?.trim()
?.toIntOrNull()

If I understood correctly:
fun main() {
val a: Int = 5
val b: Int = 10
println(a.toString())
println(b.toString())
}

Related

kotlin reduce list of map to a single map [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
How do I reduce reduce
val res = [{a=3}, {a=2, c=1}]
Into
val res = [{a=5,c=1}]` //or
val res = {a=5, c=1}
?
I tried the groupBy function but that doesn't give me the desired result. I want to sump up the values of same keys.
You can use fold operator
For example
val list = listOf(mapOf("a" to 3), mapOf("a" to 2, "c" to 1))
val res = list.fold(mutableMapOf<String, Int>()) { acc, v ->
v.forEach { (key, value) ->
if (acc.contains(key)) {
acc[key] = acc[key]!! + value
} else {
acc[key] = value
}
}
acc
}
Or by reduce operator:
val res = list.reduce { acc, map ->
val res = acc.toMutableMap()
map.forEach { (key, value) ->
res[key] = res.getOrDefault(key, 0) + value
}
res
}
Or groupBy and sumBy operators
val res = list.flatMap { it.entries }
.groupBy { it.key }
.mapValues { it.value.sumBy { v -> v.value } }
To have conflicting values summed, you can use x.asSequence().flatMap { it.asSequence() }.groupBy { it.key }.mapValues { it.value.asSequence().map { it.value }.sum() }, resulting in {a=5, c=1}.
The easiest way to do it will be to iterate over a list. Like this:
val input = listOf(
mapOf(
"a" to 2
),
mapOf(
"a" to 3,
"c" to 1
)
)
val result = mutableMapOf<String, Int>()
input.forEach { map ->
map.forEach { (key, value) ->
result[key] = result.getOrElse(key, { 0 }) + value
}
}
There are already a bunch of answers to the actual problem in the question, but if those maps are counts of items, and you're generating them yourself, you might want to create Groupings instead
val source = listOf(listOf('a', 'a', 'a'), listOf('a', 'a', 'c'))
// creating a grouping for each list, using each item as its own key
val grouped = source.map { it.groupingBy { it } }
And then you can use eachCountTo and a map to build up counts for each key
val counts = grouped.fold(mutableMapOf<Char, Int>()) { countMap, grouping ->
grouping.eachCountTo(countMap)
countMap
}
print(counts)
>> {a=5, c=1}
Good to know it exists, anyway!

Adding a list to the end of another list

I am writing a piece of code in which I need to add a list to another list.
fun a(x:Int):List<List<Int>>{
var a = 1.rangeTo(x);
var b: List<List<Int>> = emptyList();
for (i in a){
var num1 = if(i<=3) i else 4;
var list_a= 0.rangeTo(num1 - 1);
b.add(list_a);
}
return b
}
I problem is b.add(list_a) is giving error(unresolved reference).
In this function if I input println(a(2))
The output should be [[0],[0,1]]
Please help.
The reason why you're getting the unresolved reference for b.add() is because you have initialized b as a List instead of MutableList.
Please note that once initialized, you can add elements to a MutableList but not a List in Kotlin. Hence change your initialization of b as var b: MutableList<List<Int>> = mutableListOf()
fun a(x: Int): List<List<Int>> {
var a = 1.rangeTo(x)
var b: MutableList<List<Int>> = mutableListOf()
for (i in a) {
var num1 = if (i <= 3) i else 4
var list_a = 0.rangeTo(num1 - 1).toList()
b.add(list_a)
}
return b
}
Refactoring it a bit further, you can use 1..x for the range in the for loop and (0 until num1) instead of 0.rangeTo(num1 - 1) as below
fun a(x: Int): List<List<Int>> {
val listB: MutableList<List<Int>> = mutableListOf()
for (i in 1..x) {
val num1 = if (i <= 3) i else 4
val listA = (0 until num1).toList()
listB.add(listA)
}
return listB
}

Method returns tuples in Kotlin

I don't see any examples of how to use tuples in Kotlin.
The errors i get on the first line (method definition) is "unresolved reference: a" and "expecting member declaration" for Int...
private fun playingAround : Pair<out a: Int, out b: Int> {
if(b != 0) {
b = a
a = a * 2
} else {
b = a
a = a * 3
}
return Pair(a, b)
}
About the logic: b is 0 in the beginning and a has a random value.
From the second call on, we go into the else logic.
i don't feel the official doc is enough: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/index.html. I did try also without the ":" after the method name like the official doc seems to imply
-same problem
You are using incorrect syntax. It should be something like this:
private fun playingAround(a: Int, b: Int): Pair<Int, Int> {
val x: Int
val y: Int
if (b != 0) {
y = a
x = a * 2
} else {
y = a
x = a * 3
}
return Pair(x, y)
}
Note that a and b are method parameter values which cannot be reassigned, so you need variables x and y to store the result.
You can write this with much shorter syntax though:
private fun playingAround(a: Int, b: Int) = if (b != 0) Pair(a * 2, a) else Pair(a * 3, a)
Please have a look at the functions chapter of the kotlin reference and/or play around with the Kotlin koans to get familiar with Kotlin (or if, by any means, reading grammar is your favorite, have a look at the function declaration grammar instead; if you do not get what's written there, no problem. Start with the tutorials/reference instead).
One of the solutions could look like this:
private fun playingAround(a: Int, b: Int) = b.let {
if (it != 0) a * 2
else a * 3
} to a
or if you meant, that you actually want to pass a pair, then maybe the following is better:
private fun playingAround(givenPair: Pair<Int, Int>) = givenPair.let { (a, b) ->
b.let {
if (it != 0) a * 2
else a * 3
} to a
}
It's hard to really know what you wanted to accomplish as you didn't really specify what that is.
Extension function instead? For completeness:
private fun Pair<Int, Int>.playingAround() = let { (a, b) ->
b.let {
if (it != 0) a * 2
else a * 3
} to a
}
and of course: you do not need to use let, nor to use to, nor to use destructuring declarations, etc. There are just some of many possible solutions.
You can rewrite your code as the following:
private fun playingAround(a: Int, b: Int) : Pair<Int, Int> {
val tempA: Int
val tempB: Int
if(b != 0) {
tempB = a
tempA = a * 2
} else {
tempB = a
tempA = a * 3
}
return Pair(tempA, tempB)
}
And using Destructuring Declarations you can write the following:
val (a, b) = playingAround(1, 2)
Your function syntax is not correct. I suggest to study the documentation first.
To make this a bit more Kotlin-idiomatic, use if as an expression:
private fun playingAround(a: Int, b: Int): Pair<Int, Int> =
if (b != 0) {
Pair(a * 2, a)
} else {
Pair(a * 3, a)
}

Kotlin equivalent for Optional::map in Java8

Do you know if there is a shortcut for:
if (x == null) null else f(x)
For Java Optional you can just do:
x.map(SomeClass::f)
Kotlin utilizes its own approach to the idea of Option, but there're map, filter, orElse equivalents:
val x: Int? = 7 // ofNullable()
val result = x
?.let(SomeClass.Companion::f) // map()
?.takeIf { it != 0 } // filter()
?: 42 // orElseGet()
I ended up writing a full comparison here:
You can use let in this case, like this:
fun f(x : Int) : Int{
return x+1
}
var x : Int? = 1
println(x?.let {f(it)} )
=> 2
x = null
println(x?.let {f(it)} )
=> null
and as #user2340612 mentioned, it is also the same to write:
println(x?.let(::f)
You can try with let (link to documentation):
x?.let(SomeClass::f)
Example
fun f(n: Int): Int {
return n+1
}
fun main(s: Array<String>) {
val n: Int? = null
val v: Int? = 3
println(n?.let(::f))
println(v?.let(::f))
}
This code prints:
null
4

Reading multiple ints from the same line in Kotlin?

I am doing the 30 Days of Code in Kotlin on Hackerrank and I am stuck at Day 7.
How do you read multiple integers on a single line?
How is it added to an array and displayed in reverse?
I have solved it in Java but lack the syntax needed in Kotlin
Input:
4
1 4 3 2
My Code:
fun main(args: Array<String>) {
val n = readLine()!!.toInt()
var arr = Array(n)
for(i in 0 until n)
{
arr[i] = readLine()!!.toInt() //Not Working? nor does readLine()!!.split(' ').toInt()
}
for(item in arr.size - 1 downTo 0)
{
print("${item} ")
}
}
EDIT: question was updated from the original
The problem is the readLine() will read the entire line from stdin, so each time you call readLine() in the for loop it will result in a separate line being read each time.
One approach to this is to read the line, and then to split and map each value to an Int.
readLine()?.let {
val numOfValues = it.toInt()
println(numOfValues)
readLine()?.let { line ->
line.split(" ").map {
it.toInt()
}.reversed().forEach {
println(it)
}
}
}
If you want to store them in a list then you can follow this method
var items = readLine()!!.trim().split("\\s+".toRegex()).map (String::toInt)
println(items)
You can also store them in different variables like this way
var (a,b) = readLine()!!.trim().split("\\s+".toRegex()).map (String::toInt)
println(a+b)
You can also use the following code to item items splited and stored in array for a beginner approach
fun main(ags :Array<String>)
{
var item = readLine()!!.trim()
println(item[0])
}
Actually, you can refer to the official Kotlin tutorial: https://kotlinlang.org/docs/tutorials/competitive-programming.html
as mentioned in tutorial:
To make reading the input in competitive programming tasks like this more concise, you can have the following list of helper input-reading functions:
private fun readLn() = readLine()!! // string line
private fun readInt() = readLn().toInt() // single int
private fun readStrings() = readLn().split(" ") // list of strings
private fun readInts() = readStrings().map { it.toInt() } // list of ints
for your case, you can try use as below:
fun main() {
val n = readInt()
val x = readInts()
for (j in x.reversed()) {
print(j); print(" ")
}
println()
}
private fun readLn() = readLine()!! // string line
private fun readInt() = readLn().toInt() // single int
private fun readStrings() = readLn().split(" ") // list of strings
private fun readInts() = readStrings().map { it.toInt() } // list of ints