Write a kotlin program that prints the number that is repeated the most in a consecutive way - kotlin

I'm kind of stuck, I don't know how to make the second loop to start 1 position above the first loop in Kotlin.
I have an array (named myArray) with 10 elements, I need to Write a Kotlin program that prints the number that has the most consecutive repeated number in the array and also prints the number of times it appears in the sequence.
The program must parse the array from left to right so that if two numbers meet the condition, the one that appears first from left to right will be printed.
Longest: 3
Number: 8
fun main() {
val myArray: IntArray = intArrayOf(1,2,2,4,5,6,7,8,8,8)
for((index , value) in myArray.withIndex()){
var inx = index + 1
var count = 0
var longest = 0
var number = 0
for((inx,element) in myArray.withIndex()) {
if(value == element ){
count+=
}
}
if(longest < count){
longest = count
number = value
}
}
}

I'm against just dropping answers, but it is quite late for me, so I'll leave this answer here and edit it tomorrow with more info on how each part works. I hope that maybe in the meanwhile it will help you to gain some idea to where you might be going wrong.
val results = mutableMapOf<Int, Int>()
(0..myArray.size - 2).forEach { index ->
val current = myArray[index]
if (current == myArray[index + 1]) {
results[current] = (results[current] ?: 1) + 1
}
}
val (max, occurrences) = results.maxByOrNull { it.value } ?: run { println("No multiple occurrences"); return }
println("Most common consecutive number $max, with $occurrences occurrences")
Alternatively if the intArray would be a list, or if we allowed to change it to a list myArray.toList(), you could replace the whole forEach loop with a zipWithNext. But I'm pretty sure that this is a HW question, so I doubt this is the expected way of solving it.
myList.zipWithNext { a, b ->
if (a == b) results[a] = (results[a] ?: 1) + 1
}

Related

print n times number from 1. Need print (1 2 2 3 3 3 4)

I can't figure out how to solve the following problem: there is a number n. Output the numbers to the console in order separated by a space, but so that the next digit in the iteration is output as many times as it is a digit, and at the same time so that there are no more than n digits in the output. Сan anyone suggest the correct algorithm?
example: have n = 7, need print (1 2 2 3 3 3 4) in kotlin
what i try:
var n = 7
var count = 1
var i = 1
for (count in 1..n) {
for (i in 1..count) {
print(count)
}
}
}
var n = 11
var count = 1
var i = 1
var size = 0
// loop# for naming a loop in kotlin and inside another loop we can break or continue from outer loop
loop# for (count in 1..n) {
for (i in 1..count) {
print(count)
size++
if (size == n){
break#loop
}
}
}
You can use "#" for naming loops and if you want to break from that loop, you can use this syntax in kotlin. It worked for me.
For kotlin labeled break you can look at this reference: link
var count = 1
var n = 7
for(count in 1..n) {
print(count.toString().repeat(count))
}
count.toString() converts an integer to a string, .repeat() function repeats count times the string.
In case you need to add a space between each number, you can add the following:
print(" ")
Using generateSequence and Collections functions:
val n = 7
println(generateSequence(1) {it + 1}
.flatMap{e -> List(e){e}}
.take(n)
.joinToString(" "))
Your example is correct, You have to put a space between the printing
you can follow the code from this link
Kotlin lang code snippet
or the following code snippet
fun main() {
var n = 7
var count = 1
var i = 1
for (count in 1..n) {
for (i in 1..count) {
print(count)
print(' ')
}
}
}
For completeness, here's another approach where you write your own sequence function which produces individual values on demand (instead of creating intermediate lists)
sequence {
var digit = 1
while (true) {
for (i in 1..digit) yield(digit)
digit++
}
}.take(7)
.joinToString(" ")
.run(::print)
Not a big deal in this situation, but good to know!

Removing a loop to make code run faster (Kotlin) (Big O)

I'm trying a leetcode challenge and am struggling to pass the challenge due to the speed of my code:
class Solution {
fun longestPalindrome(s: String): String {
var longestPal = ""
var substring = ""
for (i in 0..s.length) {
for (j in i + 1..s.length) {
substring = s.substring(i, j)
if (substring == substring.reversed() && substring.length > longestPal.length) {
longestPal = substring
}
}
}
return longestPal
}
}
I'm a newb and not familiar with Big O notation.
I imagine if I could use just one loop I would be able to speed this code up significantly but am not sure how I would go about this.
(Not saying this is the best approach, but that is a start)
Palindromes can only be found between two same letters. So one idea is to go through the string once, and keep track of letter indexes. When you encounter a letter you already saw before, and the difference in indexes is longer than the current longest palindrome, you check for a palindrome:
fun longestPal(s: String): String {
val letters = mutableMapOf<Char, MutableList<Int>>()
var longest = ""
s.indices.forEach { index ->
val indicesForCurrentChar = letters[s[index]] ?: mutableListOf()
for (i in indicesForCurrentChar) {
if ((index - i) < longest.length) break // (1) won't be the longest anyway
val sub = s.substring(i, index + 1)
if (sub == sub.reversed()) longest = sub
}
indicesForCurrentChar.add(index)
letters[s[index]] = indicesForCurrentChar
}
return longest
}
What is costly here is the palindrome check itself (sub == sub.reversed). But the check in (1) should contain it (think of a string which is the repetition of the same letter).
I would be curious to know what other suggest online.
Your code runs in O(n^3) time, a loop within a loop within a loop, because that reversed() call iterates up to the size of the input string. You can look up Manacher's algorithm for an explanation of how to do it in linear time (O(n)), no nested iteration at all.

Count sum of all list elements until condition is satisfied

I faced the following problem: I have a list of objects. Let it be objects of the class Test:
data class Test(
var status: String, // Can be EXPIRED, WAIT
var amount: Float
)
The array is sorted, there are objects with the status EXPIRED in the beginning and after objects with the status WAIT located. I need to calculate the sum of all elements with the status EXPIRED (if they exist) and add to this sum amount of the first object with the type WAIT (if it exists). Now I have the following code:
private fun getRestructuringAmountToPay(): Float {
var i = 0
var sum = 0F
list?.forEachIndexed { iter, el ->
if (el.status != RestructingItemStatus.WAIT) {
i = iter
sum += el.amount ?: 0F
}
}
if (i + 1 < (list?.size ?: 0)) {
sum += list?.get(i+1)?.amount ?: 0F
}
return sum
}
But is there any way to improve this code and make it Kotlin-pretty? Thanks in advance for any help!
since your list is sorted and EXPIRED items are first you can use firstOrNull
to find the first item with status == WAIT
while you iterate over EXPIRED items you can use a simple variable to sum the amount and when you found the first WAIT item just assign the sum to amount
var sum: Float = 0f
list.firstOrNull {
sum += it.amount
it.status == "WAIT"
}?.apply {
this.amount = sum
}
I would go old school and use a for loop rather than the forEachIndexed method so that I can break out of the loop when I hit the first WAIT entry. I'd do something like this:
private fun getRestructuringAmountToPay(): Float {
var sum = 0F
for (el in list) {
if (el.status == RestructingItemStatus.WAIT) {
el.amount += sum
break
}
else {
sum += el.amount
}
}
return sum
}
This is a simple and elegant way to do the bare minimum amount of work without any extra iterations over the list. If you're one of the "I have to cram everything into as few lines of code as possible" crowd, there are certainly more sophisticated and compact ways to go about this. I often struggle to understand the actual advantage of such solutions.
When you say you want to find all of the elements in the list with the status "EXPIRED", that makes me think of filter(). When you say you want to sum them, that makes me think of sumBy(). And when you say you want to add that number to the first element in the list with the status "WAIT", that makes me think of first().
We can't actually use the normal sumBy() function because Test.amount is of type Float, so the closest we can do is use sumByDouble() and convert amount to a Double.
val expiredSum = list.filter { it.status == "EXPIRED" }.sumByDouble { it.amount.toDouble() }
val result = list.first { it.status == "WAIT" }.amount + expiredSum
If you don't want to throw an exception if there are no elements with the status "WAIT", use firstOrNull() instead:
val expiredSum = list.filter { it.status == "EXPIRED" }.sumByDouble { it.amount.toDouble() }
val initialValue = list.firstOrNull { it.status == "WAIT" }?.amount ?: 0F
val result = initialValue + expiredSum
Actually, your code is not doing what you want
calculate the sum of all elements with the status EXPIRED (if they exist) and add to this sum amount of the first object with the type WAIT (if it exists)
It calculates the sum of all elements with the status EXPIRED (if they exist) and add to this sum amount of the first object with the type WAIT located after the last object with EXPIRED status (if it exists) OR amount of the object with index one (if it exist) if there were no elements with status EXPIRED:
println(getRestructuringAmountToPay(listOf(Test("EXPIRED", 1f), Test("WAIT", 1f), Test("EXPIRED", 1f)))) //will print 2.0, while following original description it should be 3.0
println(getRestructuringAmountToPay(listOf(Test("WAIT", 1f), Test("WAIT", 100f)))) //Will print 100.0, while following original description it should be 1.0
To get originally desired behavior in Kotlin-way you need to do the following:
if (list == null) return 0f //get rid of nullability
val (expired, waiting) = list.partition { it.status != "WAIT" } //split original list into respectful partitions
val sum = expired.map { it.amount }.sum() + (waiting.firstOrNull()?.amount ?: 0f) //do the calculations
I'am not sure I understand your solution but respectively to your goal this:
var sum = list.filter { it.status == "EXPIRED" }.sumByDouble { it.amount.toDouble() }
list.firstOrNull{ it.status == "WAIT" }?.let { sum+=it.amount}
println(sum)
Pretty is subjective - the code below is short but admittedly does not take advantage of the "sorted" nature of the collection
fun sum(data: List<Test>): Double {
val expiredSum = data.filter { it.status == "EXPIRED" }.sumByDouble { it.amount }
val waitSum = data.find { it.status == "WAIT" }?.amount ?: 0.0
return expiredSum + waitSum
}

Create a euphonious word

All the letters of the English alphabet are divided into vowels and consonants.
A word is considered euphonious if it doesn't have three or more vowels or consonants in a row.
My goal is to create euphonious words from the discordant ones and output the minimum number of characters needed to create a euphonious word from a given word.
Examples:
Input:
schedule
Output:
1
Input:
biiiiig
Output:
2
Code
fun main() {
val word = readLine()!!.toMutableList()
checkWord(word)
}
fun isVowel(c: Char): Boolean {
val vowels = listOf('a', 'e', 'i', 'o', 'u', 'y')
return c in vowels
}
fun checkWord(word: MutableList<Char>){
var counter = 0
for (number in 0 .. word.size - 2) {
if (isVowel(word[number]) && isVowel(word[number + 1]) && isVowel(word[number + 2])) {
counter++
word.add(number + 2, 'b')
// println(word)
}
if (!isVowel(word[number]) && !isVowel(word[number + 1]) && !isVowel(word[number + 2])) {
counter++
word.add(number + 2, 'a')
// println(word)
}
}
println(counter)
}
My code is working for those examples but not for a case like eeeeeeeeeeeeeeeee where the output is supposed to be 8 but my counter is 6.
Since the list is growing as you iterate, your for loop never reaches the end of the list. Your code can be fixed by replacing
for (number in 0 .. word.size - 2) {
with
var number = -1
while (++number < word.size - 1) {
so it checks the current list size on each iteration.
I want to point out however that it is unnecessary to use a MutableList and keep enlarging it since you don't use the "fixed" euphonious list afterwards. It is also unnecessary to repeatedly search neighbors on each iteration. You can just count as you go.
fun checkWord (word: String) {
var count = 0
var currentTypeCount = 0
var lastTypeVowel = true
for (c in word) {
if (isVowel(c) == lastTypeVowel) {
if (++currentTypeCount == 3) {
count++
currentTypeCount = 1
}
} else {
lastTypeVowel = !lastTypeVowel
currentTypeCount = 1
}
}
println(count)
}
Let's analyze the modifications of your word:
eebeeeeeeeeeeeeeee
eebeebeeeeeeeeeeeee
eebeebeebeeeeeeeeeee
eebeebeebeebeeeeeeeee
eebeebeebeebeebeeeeeee
eebeebeebeebeebeebeeeee
eebeebeebeebeebeebeebeee
eebeebeebeebeebeebeebeebe
Your last 2 modification take place on the letters with index, which is bigger than your word's original length. That happens because for loop iterations number is dependent on your word's original length.
I recommend you to use while loop, as its condition is always recalculated and word.size will be updated there
var i = 0
while (i + 2 < word.size) {
// the same logic
i++
}

Fastest way to read in and print back out a 2d array in Kotlin?

The following code works for reading in a 2d array and printing it back out in Kotlin, however I imagine that with larger datasets swapping from a string to an int list would be rather slow, so is there a quicker way to do it?
fun main() {
var rowAndColumn = readLine()!!.split(" ")
var rows = rowAndColumn[0].toInt()
var columns = rowAndColumn[1].toInt()
val board = Array(rows) { IntArray(columns).toMutableList() }
for (i in 0 until rows) {
var stringColumn = readLine()!!.split("").toMutableList()
stringColumn.removeAll(listOf(""))
var column = stringColumn.map {it.toInt()}.toMutableList()
board[i] = column
}
for(i in 0 until rows) {
println(board[i].toString())
}
}
I measure this to be about 4-5 times faster than your method. It iterates Chars rather than splitting each line into Strings for each character.
var rowAndColumn = readLine()!!.split(" ")
var rows = rowAndColumn[0].toInt()
var columns = rowAndColumn[1].toInt()
val board = arrayOfNulls<IntArray?>(rows)
for (row in 0 until rows) {
board[row] = readLine()!!
.asIterable()
.mapNotNull {
val i = it.toInt() - '0'.toInt()
if (i in 0..1) i else null
}
.toIntArray()
}
board.requireNoNulls()
If you you don't mind ending up with an Array<List<Int>> instead of an Array<IntArray>, you can change that out on line 4 and remove the .toIntArray() call for a slight (~5%) improvement.
Caveat...I was reading from a text file, not the console input, so file access may have affected the comparison. Intuition tells me it's possible this would be even faster in comparison if file reading time were removed.