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++
}
Related
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!
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
}
I want to obtain the index chars or words in a string
for example
tv.text=" hey how are you, are you okay"
val res=tv.text.indexOf('h')
(have any way for put string instead of char?
output res=0
index of return only first char with h but in my tv text I have more h chars
can we return all h chars indexs
You can use filter function to get all the string indices with the required character.
val text = " hey how are you, are you okay"
val charToSearch = 'h'
val occurrences = text.indices.filter { text[it] == charToSearch }
println(occurences)
Try it yourself
And, if you want to search for strings instead of a single character, you can do this:
text.indices.filter { text.startsWith(stringToSearch, it) }
The following should work (you try to find an index if you found one in the previous iteration and you begin the folloing iteration from the previously found character instance plus 1, so that you don't find the same again and again):
fun main() {
val word = " hey how are you, are you okay"
val character = 'h'
var index: Int = word.indexOf(character)
while (index >= 0) {
println(index)
index = word.indexOf(character, index + 1)
}
}
If you want to store the indexes for later usage you can also do the following:
fun main() {
val word = " hey how are you, are you okay"
val character = 'h'
val indexes = mutableListOf<Int>()
var index: Int = word.indexOf(character)
while (index >= 0) {
index = word.indexOf(character, index + 1)
indexes.add(index)
}
println(indexes)
}
If you just want all the indices matching a char you can do this:
text.indices.filter { text[it] == 'h' }
Finding string matches is trickier, you could use Kotlin's regionMatches function to check if the part of the string starting at index matches what you're looking for:
val findMe = "you"
text.indices.filter { i ->
text.regionMatches(i, findMe, 0, findMe.length)
}
You could use a regular expression too, so long as you're careful about validating the search pattern:
Regex(findMe).findAll(text)
.map { it.range.first() } // getting the first index of each matching range
.toList()
I hope you all hear about ' Guessing Game '. The user has to guess a number and then the match goes on with generated Random number.
Now, I have written code for this, but there is a glitch and that is I am unable to understand how to write the condition for -> count variable not getting increased by 1 if just previous input number is same as the current input number by the user.
I am putting my code here:
import java.util.*
import kotlin.random.Random.Default.nextInt
fun main() {
val randomNumber = (1..100).random()
println(randomNumber)
var count: Int = 0
while (true){
val reader = Scanner(System.`in`)
var inputNumber: Int = reader.nextInt()
println("input number: $inputNumber")
if (randomNumber == inputNumber) {
println("You guessed it correct")
count += 1
print("You took $count guesses")
break
} else if (randomNumber > inputNumber) {
println("You guessed it too small")
} else {
println("You guessed it too large")
}
count += 1
print("Guess count: $count")
}
Desired output:
input number: 12
You guessed it too small
Guess count: 1
input number: 25
You guessed it too large
Guess count: 2
input number: 25
You guessed it too large
Guess count: 2
input number: 20
You guessed it right
Guess count: 3
My output:
input number: 12
You guessed it too small
Guess count: 1
input number: 25
You guessed it too large
Guess count: 2
input number: 25
You guessed it too large
Guess count: 3
input number: 20
You guessed it right
Guess count: 4
You can add a variable for tracking the previous input. It should have an initial value of null so it's not possible to accidentally have it tell you your first guess is a repeated one. Before adding to the count, check for the repeated value and continue the loop if it's a repeat. I'd also put the count += 1 before you check whether the guess is correct so it doesn't have to appear in two places in your code. I also moved the creation of the Scanner before the loop so you aren't redundantly recreating it each time it's used.
fun main() {
val randomNumber = (1..100).random()
println(randomNumber)
var count: Int = 0
var previousInput: Int? = null
val reader = Scanner(System.`in`)
while (true) {
val inputNumber: Int = reader.nextInt()
if (inputNumber == previousInput) {
println("That is the same as your previous guess.")
continue
}
count += 1
previousInput = inputNumber
if (randomNumber == inputNumber) {
println("You guessed it correct")
print("You took $count guesses")
break
} else if (randomNumber > inputNumber) {
println("You guessed it too small")
} else {
println("You guessed it too large")
}
println("You've taken $count guess(es)")
}
}
Here's the problem in which I encountered this issue:
The function should compare the value at each index position and score a point if the value for that position is higher. No point if they are the same. Given a = [1, 1, 1] b = [1, 0, 0] output should be [2, 0]
fun compareArrays(a: Array<Int>, b: Array<Int>): Array<Int> {
var aRetVal:Int = 0
var bRetVal:Int = 0
for(i in 0..2){
when {
a[i] > b[i] -> aRetVal + 1 // This does not add 1 to the variable
b[i] > a[i] -> bRetVal++ // This does...
}
}
return arrayOf(aRetVal, bRetVal)
}
The IDE even says that aRetVal is unmodified and should be declared as a val
What others said is true, but in Kotlin there's more. ++ is just syntactic sugar and under the hood it will call inc() on that variable. The same applies to --, which causes dec() to be invoked (see documentation). In other words a++ is equivalent to a.inc() (for Int or other primitive types that gets optimised by the compiler and increment happens without any method call) followed by a reassignment of a to the incremented value.
As a bonus, consider the following code:
fun main() {
var i = 0
val x = when {
i < 5 -> i++
else -> -1
}
println(x) // prints 0
println(i) // prints 1
val y = when {
i < 5 -> ++i
else -> -1
}
println(y) // prints 2
println(i) // prints 2
}
The explanation for that comes from the documentation I linked above:
The compiler performs the following steps for resolution of an operator in the postfix form, e.g. a++:
Store the initial value of a to a temporary storage a0;
Assign the result of a.inc() to a;
Return a0 as a result of the expression.
...
For the prefix forms ++a and --a resolution works the same way, and the effect is:
Assign the result of a.inc() to a;
Return the new value of a as a result of the expression.
Because
variable++ is shortcut for variable = variable + 1 (i.e. with assignment)
and
variable + 1 is "shortcut" for variable + 1 (i.e. without assignment, and actually not a shortcut at all).
That is because what notation a++ does is actually a=a+1, not just a+1. As you can see, a+1 will return a value that is bigger by one than a, but not overwrite a itself.
Hope this helps. Cheers!
The equivalent to a++ is a = a + 1, you have to do a reassignment which the inc operator does as well.
This is not related to Kotlin but a thing you'll find in pretty much any other language