Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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()
    }
}
like image 824
Cerber Avatar asked Jul 14 '26 03:07

Cerber


2 Answers

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
like image 50
aSemy Avatar answered Jul 17 '26 08:07

aSemy


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.

like image 43
rossum Avatar answered Jul 17 '26 08:07

rossum



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!