Expected output to file 'numbers.txt' did not meet the requirements - kotlin

Create a program that ask a user to type positive integers. Each positive integer is saved to a file called numbers.txt. When a user types -1, the program reads the file, and add numbers to a list. Finally, the program prints the count and the average of typed numbers from a list. If the typed integer is not positive, the program prints "The number must be positive" message.
So far, my program is as follows:
import java.util.*
import java.io.File
fun main(args: Array<String>) {
val list = mutableListOf<Int>()
var counter = 0
while(true){
val reader = Scanner(System.`in`)
var file = File("numbers.txt")
println("Type a positive integer (-1 to exit):")
var input_num = reader.nextInt()
if (input_num >= 0) {
list.add(input_num)
counter++
}
else if (input_num < -1){
println("The number must be positive")
}
else if (input_num == -1){
break
}
}
println("You typed $counter numbers.")
println("The average is ${list.average()}.")
}
The output is working as expected 1) counter displays the desirable number and 2) the average of the list is also displayed correctly.
Although, my issue is that no numbers were added to the actual .txt file. I am sorry for any mistake made on by behalf this is my first post and I am completely new to Kotlin language. Any feedback is very appreciated.

Related

Count isn't counting the amount of string items in an array in Kotlin

I just want to count the words in the array using .count but its giving the following error:
error: type mismatch: inferred type is String but (TypeVariable(T)) -> Boolean was expected
println(sentArr.count(x))
**code**:
fun main() {
var sentence = "Bob hit a ball, the hit BALL flew
far after it was hit."
var sentArr = sentence.split(" ")
var bannedWords = arrayOf("ball")
for(x in sentArr){
println(sentArr.count(x))
}
}
If I am correctly guessing what you're trying to do, this is what you're looking for:
for(x in sentArr){
println(sentArr.count { it == x })
}
This means to count how many of the Strings in the array are the same as x.
If you just want to count the words in the array, you can simply write sentArr.size or sentArr.count(). No need for a loop

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

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
}

How do I fix a NullPointerException on Kotlin?

I am a beginner in programming and I am trying to solve a math problem on Kotlin. The problem is:
"Challenge -> You must read 5 integer values. Then show how many reported values ​​are even, how many reported values ​​are odd, how many reported values ​​are positive, and how many reported values ​​are negative. Assume that the number zero is positive, but it cannot be considered positive or negative.
Input -> You will receive 5 integer values (-5, 0, -3, -4, 12).
Exit -> Display the message as shown in the output example below, being one message per line and not forgetting the end of the line after each one. The output should show (3 evens, 2 odds, 1 positive, 3 negatives)"
This was what I thought could be the solution:
fun main(args: Array<String>) {
val integers= mutableListOf<Int>()
var evens = mutableListOf<Int>()
var odds = mutableListOf<Int>()
var positives = mutableListOf<Int>()
var negatives = mutableListOf<Int>()
for (i in 1..5) { integers.add(readLine()!!.toInt()) }
for (i in integers) {
if (i % 2 == 0) { evens.add(i) }
if (i % 2 != 0) { odds.add(i) }
if (i > 0) { positives.add(i) }
if (i < 0) { negatives.add(i) }
}
println("${evens.size} even(s)")
println("${odds.size} odd(s)")
println("${positives.size} positive(s)")
println("${negatives.size} negative(s)")
}
This is returning the following message:
Exception in thread "main" java.lang.NullPointerException
at FileKt.main (File.kt:9)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (NativeMethodAccessorImpl.java:-2)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
How can I fix it? What did I do wrong? What am I forgetting?
Short answer: You don't put any input.
Long answer:
If you programming in https://play.kotlinlang.org/ you gonna got that error.
Because it dont have read input.
But same example in
with input gonna be ok.

Kotlin - Random numbers without repeating

I have a question, how to prevent random numbers from being repeated.
By the way, can someone explain to me how to sort these random numbers?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView = findViewById<TextView>(R.id.textView)
val button = findViewById<Button>(R.id.buttom)
button.setOnClickListener {
var liczba = List(6){Random.nextInt(1,69)}
textView.text = liczba.toString()
}
}
There are three basic methods to avoid repeating 'random' numbers. If they don't repeat then they are not really random of course.
with a small range of numbers, randomly shuffle the numbers and pick them in order after the shuffle.
with a medium size range of numbers, record the numbers you have picked, and reject any repeats. This will get slow if you pick a large percentage of the numbers available.
with a very large range of numbers you need something like an encryption: a one-to-one mapping which maps 0, 1, 2, 3 ... to the numbers in the (large) range. For example a 128 bit encryption will give an apparently random ordering of non-repeating 128-bit numbers.
Sequences are a great way to generate streams of data and limit or filter the results.
import kotlin.random.Random
import kotlin.random.nextInt
val randomInts = generateSequence {
// this lambda is the source of the sequence's values
Random.nextInt(1..69)
}
// make the values distinct, so there's no repeated ints
.distinct()
// only fetch 6 values
// Note: It's very important that the source lambda can provide
// this many distinct values! If not, the stream will
// hang, endlessly waiting for more unique values.
.take(6)
// sort the values
.sorted()
// and collect them into a Set
.toSet()
run in Kotlin Playground
To make sure this works, here's a property-based-test using Kotest.
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldBeMonotonicallyIncreasing
import io.kotest.matchers.collections.shouldBeUnique
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.property.Arb
import io.kotest.property.arbitrary.positiveInts
import io.kotest.property.checkAll
import kotlin.random.Random
import kotlin.random.nextInt
class RandomImageLogicTest : FunSpec({
test("expect sequence of random ints is distinct, sorted, and the correct size") {
checkAll(Arb.positiveInts(30)) { limit ->
val randomInts = generateSequence { Random.nextInt(1..69) }
.distinct()
.take(limit)
.sorted()
.toSet()
randomInts.shouldBeMonotonicallyIncreasing()
randomInts.shouldBeUnique()
randomInts.shouldHaveSize(limit)
}
}
})
The test passes!
Test Duration Result
expect sequence of random ints is di... 0.163s passed
val size = 6
val s = HashSet<Int>(size)
while (s.size < size) {
s += Random.nextInt(1,69)
}
I create simple class, in constructor you enter "from" number (minimal possible number) and "to" (maximal posible number), class create list of numbers.
"nextInt()" return random item from collection and remove it.
class RandomUnrepeated(from: Int, to: Int) {
private val numbers = (from..to).toMutableList()
fun nextInt(): Int {
val index = kotlin.random.Random.nextInt(numbers.size)
val number = numbers[index]
numbers.removeAt(index)
return number
}
}
usage:
val r = RandomUnrepeated(0,100)
r.nextInt()
Similar to #IR42's answer, you can do something like this
import kotlin.random.Random
fun getUniqueRandoms() = sequence {
val seen = mutableSetOf<Int>()
while(true) {
val next = Random.nextInt()
// add returns true if it wasn't already in the set - i.e. it's not a duplicate
if (seen.add(next)) yield(next)
}
}
fun main() {
getUniqueRandoms().take(6).sorted().forEach(::println)
}
So getUniqueRandoms creates an independent sequence, and holds its own internal state of which numbers it's produced. For the caller, it's just a basic sequence that produces unique values, and you can consume those however you like.
Like #rossum says, this really depends on how many you're going to produce - if you're generating a lot, or this sequence is really long-lived, that set of seen numbers will get very large over time. Plus it will start to slow down as you get more and more collisions, and have to keep trying to find one that hasn't been seen yet.
But for most situations, this kind of thing is just fine - you'd probably want to benchmark it if you're producing, say, millions of numbers, but for something like 6 it's not even worth worrying about!
You can use Set and MutableSet instead of List:
val mySet = mutableSetOf<Int>()
while (mySet.size < 6)
mySet.add(Random.nextInt(1, 69))

Need help in creating ' Guesing Game ' in Kotlin. Unable to check for previous input number and match it with current input number

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)")
}
}