On the Android Studio emulator The user is required to enter a maximum of 10 numbers. When I put in the number 1 the output shows 0 instead of 1 (this is for the min number; the max works perfectly fine) Can anyone please assist me in this problem. I tried using minOf() and max() nothing worked Below is a snippet of my source code:
val arrX = Array(10) { 0 }
.
.
.
.
findMinAndMaxButton.setOnClickListener {
fun getMin(arrX: Array<Int>): Int {
var min = Int.MAX_VALUE
for (i in arrX) {
min = min.coerceAtMost(i)
}
return min
}
fun getMax(arrX: Array<Int>): Int {
var max = Int.MIN_VALUE
for (i in arrX) {
max = max.coerceAtLeast(i)
}
return max
}
output.text = "The Min is "+ getMin(arrX) + " and the Max is " + getMax(arrX)
}
}
}
Is there anything that can be done to get this work?
You're initialising arrX to a bunch of zeroes, and 0.coerceAtMost(someLargerNumber) will always stick at 0.
Without seeing how you set the user's numbers it's hard to say what you need to do - but since you said the user enters a maximum of 10 numbers, at a guess there are some gaps in your array, i.e. indices that are still set to 0. If so, they're going to be counted in your min calculation.
You should probably use null as your default value instead - that way you can just ignore those in your calculations:
val items = arrayOfNulls<Int?>(10)
// this results in null, because there are no values - handle that however you like
println(items.filterNotNull().minOrNull())
>> null
// set values on some of the indices
(3..5).forEach { items[it] = it }
// now this prints 3, because that's the smallest of the numbers that -do- exist
println(items.filterNotNull().minOrNull())
>> 3
Related
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 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)")
}
}
I was solving a problem on codeforces in which I had to sum up the digits of a big number (it can have up to 100k digits) and I'd have to repeat that process until there is only one digit left and count the number of times I did that and I came up with a working solution, however I'd like to know if some things could have been done in a more "Kotlin-ish like way", so given:
fun main(args: Array<String>) {
println(transform(readLine()!!))
}
fun transform(n: String): Int {
var count = 0
var sum : Int
var s = n
while(s.length > 1) {
sum = (0 until s.length).sumBy { s[it].toInt() - '0'.toInt() }
s = sum.toString()
count++
}
return count
}
sum = (0 until s.length).sumBy { s[it].toInt() - '0'.toInt() } is there a way to I guess map the sum of digits in the string to the sum variable, or in general a better approach than the one I used?
When converting a Char to an Int it converts it to the ASCII value so I had to add "-'0'.toInt()" is there a faster way (not that it's too much to write, asking out of curiosity)?
How to make the String n mutable without creating a new String s and manipulating it? Or is that the desired (and only) way?
P.S. I'm a beginner with Kotlin.
When converting a Char to an Int it converts it to the ASCII value so I had to add "-'0'.toInt()" is there a faster way (not that it's too much to write, asking out of curiosity)?
You can simply write s[it] - '0', because subtracting Chars in Kotlin already gives you an Int:
public class Char ... {
...
/** Subtracts the other Char value from this value resulting an Int. */
public operator fun minus(other: Char): Int
...
}
But why are looping over the indexes when you could loop over the Chars directly?
sum = s.sumBy { it - '0' }
This is a functional (and recursive) style to solve it:
private fun sum(num: String, count: Int) : Int {
return num
//digit to int
.map { "$it".toInt() }
//sum digits
.sum()
//sum to string
.toString()
//if sum's length is more than one, do it again with incremented count. Otherwise, return the current count
.let { if (it.length > 1) sum(it, count + 1) else count }
}
And you call it like this:
val number = "2937649827364918308623946..." //and so on
val count = sum(number, 0)
Hope it helps!
val listNumbers = generateSequence(1) { it + 1 }
val listNumber1to100 = listNumbers.takeWhile { it < 100 }
val secNum:Unit = listNumber1to100.forEach {it}
println(listNumber1to100.asSequence().filter { it%(listNumber1to100.forEach { it })!=0 }.toList())
I have an error in reminder sign!
This is Error: None of the following functions can be called with the arguments supplied
In your first approach, the error appears in this line:
it%(listNumber1to100.forEach { it })
A Byte, Double, Float, Int, Long or Short is prefered right after the % operator, however, forEach is a function which the return type is Unit.
In your second approach, you have the correct expression in isPrime(Int). Here are some suggestions for you:
listNumber1to100 is excluding 100 in your code, if you want to include 100 in listNumber1to100, the lambda you pass to takeWhile should be changed like this:
val listNumber1to100 = listNumbers.takeWhile { it <= 100 }
listNumber1to100.asSequence() is redundant here since listNumber1too100 is itself a TakeWhileSequence which implements Sequence.
isPrime(Int) is a bit confusing since it is check for isComposite and it does not work for every input it takes(it works for 1 to 99 only). I will rewrite it in this way:
fun isPrime(num: Int): Boolean = if (num <= 1) false else !(2..num/2).any { num % it == 0 }
Since prime number must be positive and 1 is a special case(neither a prime nor composite number), it just return false if the input is smaller or equal to 1. If not, it checks if the input is divisible by a range of number from 2 to (input/2). The range ends before (input/2) is because if it is true for num % (num/2) == 0, it is also true for num % 2 == 0, vise versa. Finally, I add a ! operator before that because a prime number should not be divisible by any of those numbers.
Finally, you can filter a list by isPrime(Int) like this:
println(listNumber1to100.filter(::isPrime).toList())
PS. It is just for reference and there must be a better implementation than this.
To answer your question about it, it represents the only lambda parameter inside a lambda expression. It is always used for function literal which has only one parameter.
The error is because the expression: listNumber1to100.forEach { it } - is not a number, it is a Unit (ref).
The compiler try to match the modulo operator to the given function signatures, e.g.: mod(Byte) / mod(Int) / mod(Long) - etc.
val listNumbers = generateSequence(1) { it + 1 }
val listNumber1to100 = listNumbers.takeWhile { it < 100 }
fun isPrime(num: Int): Boolean = listNumber1to100.asSequence().any { num%it==0 && it!=num && it!=1 }
println(listNumber1to100.asSequence().filter { !isPrime(it)}.toList())
I found this solution and worked
But why can I have a non-number here in the right side of reminder
I need to write a method that returns me the smallest distance (which is a whole number value) within an Array List called "babyTurtles". There are 5 turtles within this array list and they all move a random distance each time the program is ran.
I've been trying to figure out how to do it for an hour and all I've accomplished is making myself frustrated and coming here.
p.s.
In my class we wrote this code to find the average distance moved by the baby turtles:
public double getAverageDistanceMovedByChildren() {
if (this.babyTurtles.size() == 0) {
return 0;
}
double sum = 0;
for (Turtle currentTurtle : this.babyTurtles) {
sum = sum + currentTurtle.getDistanceMoved();
}
double average = sum / this.babyTurtles.size();
return average;
}
That's all I've got to work on, but I just can't seem to find out how to do it.
I'd really appreciate it if you could assist me.
This will give you the index in the array list of the smallest number:
int lowestIndex = distanceList.indexOf(Collections.min(distanceList));
You can then get the value using this:
int lowestDistance = distanceList.get(lowestIndex);