Calculate the numbers without separating them - kotlin

I can't solve this problem, how to separate the numbers and do the required arithmetic
https://codeforces.com/group/MWSDmqGsZm/contest/219158/problem/O
This is my code , I don't know how true it is
fun main(args:Array<String>) {
val scanner = Scanner(System.`in`)
var s: String = read()!!
var c: Char? = null
var a: String = ""
var b: String = ""
var t: Boolean = true
for (i in 1..s.length) {
if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
c = s[i]
t = false
}else{
if(t){
a+=s[i]
}else{
b+=s[i]
}
}
}
if(c=='+'){
println(a+b)
}else if (c=='-'){
println( "$a - $b" )
}else if (c=='*'){
println("$a * $b")
}else{
println("$a / $b")
}

Try this code:
fun main() {
val str = readLine()!!
val (index, operator) = str.findAnyOf(listOf("+", "-", "*", "/"))!!
val a = str.substring(0, index).toInt()
val b = str.substring(index + 1).toInt()
val result = when (operator) {
"+" -> a + b
"-" -> a - b
"*" -> a * b
"/" -> a / b
else -> -1
}
println(result)
}
findAnyOf documentation:
Finds the first occurrence of any of the specified [strings] in this char sequence.
Returns A pair of an index of the first occurrence of matched string from [strings] and the string matched or null if none of [strings] are found.
Rest of the logic is quite straightforward.

Related

HashMap getting value by the Key

How to compare each char from the String with Keys from the HashMap?
I have used loops of course and change each Key to Char.
val romanNumbers = HashMap<String, Int>()
romanNumbers[""] = 0
romanNumbers["I"] = 1
romanNumbers["V"] = 5
Instead of string.get(i) I also tried string[i]
for (i in string.indices){
for ((k, v) in romanNumbers) {
if (string.length == 1) {
res1 = romanNumbers.getValue(string)
}
if (string.get(i) == k.single()) {
num1 = v
}
if (string[i + 1] == k.single()) {
num2 = v
}
}
}
error
Exception in thread "main" java.util.NoSuchElementException: Char sequence is empty.
at kotlin.text.StringsKt___StringsKt.single(_Strings.kt:223)
at CodeWars.MappingTrainingKt.decode(MappingTraining.kt:38)
at CodeWars.MappingTrainingKt.main(MappingTraining.kt:4)
at CodeWars.MappingTrainingKt.main(MappingTraining.kt)

How to solve PW Generator can´t handle specific Chars?

I´m new to Kotlin so first I start with a Password Generator. I do use IntelliJIDea
fun main() {
var helper = Int
var counter = 0
val counterOfPwCha = 10
var pwString = ""
val opportunityArray = arrayOf('A','C','a','c','B','b','D','d','E','e','F','f','#','+','*','$','%','&','§','G','g','H','h','I','i','J','j','k','K','1','2','3','4','5','6','7','8','9',
'l','L','M','m','N','n','O','o','P','p','Q','q','R','r','S','s','T','t','U','u','V','v','W','w','Y','y','X','x','Z','z','<','>','|','?','!',)
while (counter <= counterOfPwCha)
{
helper = (0..73).random()
pwString += opportunityArray[helper]
counter++
}
println(pwString)
}
it workes fine, but the output isn´t what I expected.
Example: +3�2L%II>J�
So it cant handle some of my Chars, I can debug it until I know what kind of Char he can´t handle with and delete them from the Array, but they are all some typical PW Chars, so my question is:
How can I let Kotlin know, how to Handle these ASCI2 chars?
Or is it because of the $?
Avoid hardcoded numbers like the "73" in your range, it's way too error prone!
If you still get funny characters, put in some println that shows each character's numeric value so that you can lookup it using "man ascii".
A more Kotlin-like code would be:
fun pwgen() {
val counterOfPwCha = 10
val charset = ('A'..'Z') + ('a'..'z') + ('0'..'9') + listOf('#', '+', '*', '$', '%', '&', '§', '<', '>', '|', '?', '!')
val pwString = (1..counterOfPwCha)
.map {
val randomArrayIndex = charset.indices.random()
charset[randomArrayIndex]
}
.onEach { c -> println("Character $c = " + c.toInt()) }
.joinToString("")
println(pwString)
}
fun main() {
var helper = Int
var counter = 0
val counterOfPwCha = 10
var pwString = ""
val opportunityArray = arrayOf('A','C','a','c','B','b','D','d','E','e','F','f','#','+','*','$','%','&','§','G','g','H','h','I','i','J','j','k','K','1','2','3','4','5','6','7','8','9',
'l','L','M','m','N','n','O','o','P','p','Q','q','R','r','S','s','T','t','U','u','V','v','W','w','Y','y','X','x','Z','z','<','>','|','?','!',)
while (counter <= counterOfPwCha)
{
helper = (0..73).random()
pwString += opportunityArray[helper]
counter++
}
println(pwString)
}

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: Run length encoding

The program works, however, I still get a logical error: the final letter doesn't run through. For example, when I enter aaaabbbbccccdddd the output I get is a4b4c4 but there is no d4.
fun main () {
val strUser = readLine()!!.toLowerCase()
val iLength = strUser!!.length
var iMatch : Int = 0
var chrMatch : Char = strUser[0]
for (i in 0..iLength) {
if (strUser[i] == chrMatch) {
iMatch += 1
}else {
print("$chrMatch$iMatch")
chrMatch = strUser[i]
iMatch = 1
}
}
}
There are many solutions, but the best is RegExp
fun encode(input: String): String =
input.replace(Regex("(.)\\1*")) {
String.format("%d%s", it.value.length, it.groupValues[1])
}
demo
Test result
println(encode("aaaabbbbccccdddd")) // 4a4b4c4d
strUser contains chars by indexes from 0 to iLength - 1 so you have to write for (i in 0 until iLength) instead of for (i in 0..iLength)
But Tenfour04 is completely right, you can just iterate strUser without indexes:
fun main() {
val strUser = readLine()!!.toLowerCase()
var iMatch: Int = 0
var chrMatch: Char = strUser[0]
for (char in strUser) {
if (char == chrMatch) {
iMatch += 1
} else {
print("$chrMatch$iMatch")
chrMatch = char
iMatch = 1
}
}
}
fun main () {
val strUser = readLine()!!.toLowerCase()
var iMatch : Int = 0
var chrMatch : Char = strUser[0]
for (char in strUser+1) {
if (char == chrMatch) {
iMatch += 1
}else {
print("$chrMatch$iMatch")
chrMatch = char
iMatch = 1
}
}
}
fun runLengthEncoding(inputString: String): String {
val n=inputString.length
var i : Int =0
var result : String =""
while(i<n){
var count =1
while(i<n-1 && inputString[i] == inputString[i+1]){
count ++
i++
}
result=result.toString()+count.toString()+inputString[i].toString()
i++
}
return result
}

A very basic exercise help-----Kotlin

Im trying to do this exercise
https://www.hackerrank.com/challenges/compare-the-triplets/problem?h_r=next-challenge&h_v=zen
I already wrote the code but the result is not right and for my eyes its all good
Could somebody pls tell me whats wrong??
thx
import java.util.Scanner
fun main(){
var loop = 0
var score = Array<Int>(2){0}
val reader = Scanner(System.`in`)
var alice:String = readLine().toString()
var bob:String = readLine().toString()
val numerosa: List<String> = alice.split(" ")
val numerosb:List<String> = bob.split(" ")
for(a in 3..3) {
when (numerosa[loop].toInt()) {
in numerosb[loop].toInt() + 1..100 -> score[0] += 1
in numerosb[loop].toInt() - 1..0 -> score[1] += 1
}
loop += 1
}
println("${score[0]} ${score[1]}")
}
You could do it something like this, you have multiple variables which were not required so I cleaned up the code.
val score = Array(2) { 0 }
val aliceNumbers = readLine()!!.split(" ").map(String::toInt)
val bobNumbers = readLine()!!.split(" ").map(String::toInt)
require(aliceNumbers.size == 3 && bobNumbers.size == 3) { "There must be 3 numbers for each" }
require(!aliceNumbers.any { it !in 1..100 } || !bobNumbers.any { it !in 1..100 }) { "Numbers must be in range 1 to 100" }
for (a in 0..2) {
if(aliceNumbers[a] > bobNumbers[a]) score[0] += 1
if(aliceNumbers[a] < bobNumbers[a]) score[1] += 1
}
println("${score[0]} ${score[1]}")