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
}
Related
I'm working on Splay Tree. I have a lot of command input (add, delete and etc), Hence the output is also huge (32MB of text in a txt file)
I have a memory problem, I am currently using two MultitableList and I have 200 MB of virtual memory (128 MB is needed for the project)
I run on Linux with the command:
$ kotlinc Kotlin.kt -include-runtime -d outPutFile.jar
$ /usr/bin/time -v java -jar outPutFile.jar
result: Maximum resident set size (kbytes): 249732 (With each launch different sizes but about 200)
how can i reduce the size? I need to change the size after each cycle
class SplayTree {
var ROOT: Node? = null
class Node(val key: Long, var value: String?) {
var _parent: SplayTree.Node? = null
var _RightChild: SplayTree.Node? = null
var _LeftChild: SplayTree.Node? = null
... there is a code here ...
// for output
override fun toString(): String {
if (_parent == null) {
return "[${key} ${value}]"
} else {
return "[${key} ${value} ${_parent!!.key}]"
}
}
}
... there is a code here ...
override fun toString(): String {
if (ROOT == null) {
return "_"
}
println(ROOT)
var NOWqueueList: List<Node?> = listOf(ROOT)
var BABYqueue: MutableList<Node?> = MutableList(0) { null }
//var NOWqueueList = Array<Node?>(1, {ROOT}) // Array
//var BABYqueue = Array<Node?>(1, {null}) // Array
//var n = 1 // Array
for (h in 1 until height(ROOT)) {
// for Array
//var pos = -1
//n *= 2
//BABYqueue = Array<Node?>(n, {null}) //for future line
for (ROOTList in NOWqueueList) {
//pos++ // Array
if ( ROOTList != null){
//left
if (ROOTList.haveLeftBaby()) {
//BABYqueue[pos] = ROOTList._LeftChild // Array
BABYqueue.add(ROOTList._LeftChild)
print(ROOTList._LeftChild.toString())
print(" ")
} else {
//BABYqueue[pos] = null // Array
BABYqueue.add(null)
print("_ ")
}
//pos++ // Array
//right
if (ROOTList.haveRightBaby()) {
//BABYqueue[pos] = ROOTList._RightChild // Array
BABYqueue.add(ROOTList._RightChild)
print(ROOTList._RightChild.toString())
print(" ")
} else {
//BABYqueue[pos] = null
BABYqueue.add(null)
print("_ ")
}
} else{ //если пустой то + 2 "_"
//BABYqueue[pos] = null // Array
//pos++ // Array
//BABYqueue[pos] = null // Array
BABYqueue.add(null)
BABYqueue.add(null)
print("_ _ ")
}
}
//NOWqueueList.clear() //worked when was MultitableList
NOWqueueList = BABYqueue.toList() // equate
//NOWqueueList = BABYqueue.clone() // Array
//println(NOWqueueList.joinToString(" ")) // вывожу готовый
println()
BABYqueue.clear()
}
//NOWqueueList.clear()
BABYqueue.clear()
return " end="
}
}
fun main() {
... there is a code here ...
}
I tried using Array, it still came out as with MultitableList
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.
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)
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(""))
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]}")