diff --git a/libraries/stdlib/common/src/generated/_Arrays.kt b/libraries/stdlib/common/src/generated/_Arrays.kt index 6da164b0f28..4e6674f72ae 100644 --- a/libraries/stdlib/common/src/generated/_Arrays.kt +++ b/libraries/stdlib/common/src/generated/_Arrays.kt @@ -5447,6 +5447,213 @@ public fun CharArray.reversedArray(): CharArray { return result } +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun Array.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun ByteArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun ShortArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun IntArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun LongArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun FloatArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun DoubleArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun BooleanArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +public fun CharArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun Array.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun ByteArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun ShortArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun IntArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun LongArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun FloatArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun DoubleArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun BooleanArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +public fun CharArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + /** * Sorts elements in the array in-place according to natural sort order of the value returned by specified [selector] function. * diff --git a/libraries/stdlib/common/src/generated/_Collections.kt b/libraries/stdlib/common/src/generated/_Collections.kt index e44f17614ed..9ff2f45e098 100644 --- a/libraries/stdlib/common/src/generated/_Collections.kt +++ b/libraries/stdlib/common/src/generated/_Collections.kt @@ -906,6 +906,19 @@ public fun Iterable.reversed(): List { return list } +/** + * Randomly shuffles elements in this list in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.3") +public fun MutableList.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + this[j] = this.set(i, this[j]) + } +} + /** * Sorts elements in the list in-place according to natural sort order of the value returned by specified [selector] function. * diff --git a/libraries/stdlib/common/src/generated/_UArrays.kt b/libraries/stdlib/common/src/generated/_UArrays.kt index 566f443ada2..80670df9b91 100644 --- a/libraries/stdlib/common/src/generated/_UArrays.kt +++ b/libraries/stdlib/common/src/generated/_UArrays.kt @@ -2702,6 +2702,106 @@ public inline fun UShortArray.reversedArray(): UShortArray { return UShortArray(storage.reversedArray()) } +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UIntArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun ULongArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UByteArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UShortArray.shuffle(): Unit { + shuffle(Random) +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UIntArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun ULongArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UByteArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + +/** + * Randomly shuffles elements in this array in-place using the specified [random] instance as the source of randomness. + * + * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UShortArray.shuffle(random: Random): Unit { + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } +} + /** * Sorts elements in the array in-place descending according to their natural sort order. */ diff --git a/libraries/stdlib/jvm/src/kotlin/collections/CollectionsJVM.kt b/libraries/stdlib/jvm/src/kotlin/collections/CollectionsJVM.kt index 468331f9f2d..c35fb7a6246 100644 --- a/libraries/stdlib/jvm/src/kotlin/collections/CollectionsJVM.kt +++ b/libraries/stdlib/jvm/src/kotlin/collections/CollectionsJVM.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -28,6 +28,20 @@ public fun listOf(element: T): List = java.util.Collections.singletonList public inline fun java.util.Enumeration.toList(): List = java.util.Collections.list(this) +/** + * Returns a new list with the elements of this list randomly shuffled. + */ +@SinceKotlin("1.2") +public actual fun Iterable.shuffled(): List = toMutableList().apply { shuffle() } + +/** + * Returns a new list with the elements of this list randomly shuffled + * using the specified [random] instance as the source of randomness. + */ +@SinceKotlin("1.2") +public fun Iterable.shuffled(random: java.util.Random): List = toMutableList().apply { shuffle(random) } + + @kotlin.internal.InlineOnly internal actual inline fun copyToArrayImpl(collection: Collection<*>): Array = kotlin.jvm.internal.collectionToArray(collection) diff --git a/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt b/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt index 8fd30762dae..fd1a4ad649f 100644 --- a/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt +++ b/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -71,16 +71,3 @@ public actual inline fun MutableList.shuffle() { public inline fun MutableList.shuffle(random: java.util.Random) { java.util.Collections.shuffle(this, random) } - -/** - * Returns a new list with the elements of this list randomly shuffled. - */ -@SinceKotlin("1.2") -public actual fun Iterable.shuffled(): List = toMutableList().apply { shuffle() } - -/** - * Returns a new list with the elements of this list randomly shuffled - * using the specified [random] instance as the source of randomness. - */ -@SinceKotlin("1.2") -public fun Iterable.shuffled(random: java.util.Random): List = toMutableList().apply { shuffle(random) } diff --git a/libraries/stdlib/src/kotlin/collections/Collections.kt b/libraries/stdlib/src/kotlin/collections/Collections.kt index 7635efb05ce..3980e3ad08a 100644 --- a/libraries/stdlib/src/kotlin/collections/Collections.kt +++ b/libraries/stdlib/src/kotlin/collections/Collections.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -10,6 +10,7 @@ package kotlin.collections import kotlin.contracts.* +import kotlin.random.Random internal object EmptyIterator : ListIterator { override fun hasNext(): Boolean = false @@ -266,6 +267,15 @@ public inline fun C.ifEmpty(defaultValue: () -> R): R where C : Collectio @kotlin.internal.InlineOnly public inline fun <@kotlin.internal.OnlyInputTypes T> Collection.containsAll(elements: Collection): Boolean = this.containsAll(elements) + +/** + * Returns a new list with the elements of this list randomly shuffled + * using the specified [random] instance as the source of randomness. + */ +@SinceKotlin("1.3") +public fun Iterable.shuffled(random: Random): List = toMutableList().apply { shuffle(random) } + + internal fun List.optimizeReadOnlyList() = when (size) { 0 -> emptyList() 1 -> listOf(this[0]) diff --git a/libraries/stdlib/src/kotlin/collections/MutableCollections.kt b/libraries/stdlib/src/kotlin/collections/MutableCollections.kt index 99ce9cb1780..0ac419e3017 100644 --- a/libraries/stdlib/src/kotlin/collections/MutableCollections.kt +++ b/libraries/stdlib/src/kotlin/collections/MutableCollections.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -225,14 +225,6 @@ private fun MutableIterable.filterInPlace(predicate: (T) -> Boolean, pred } -/** - * Returns a new list with the elements of this list randomly shuffled - * using the specified [random] instance as the source of randomness. - */ -@SinceKotlin("1.3") -public fun Iterable.shuffled(random: Random): List = toMutableList().apply { shuffle(random) } - - /** * Removes the element at the specified [index] from this list. * In Kotlin one should use the [MutableList.removeAt] function instead. @@ -307,19 +299,3 @@ private fun MutableList.filterInPlace(predicate: (T) -> Boolean, predicat return false } } - -/** - * Randomly shuffles elements in this mutable list using the specified [random] instance as the source of randomness. - * - * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm - */ -@SinceKotlin("1.3") -public fun MutableList.shuffle(random: Random): Unit { - for (i in lastIndex downTo 1) { - val j = random.nextInt(i + 1) - val copy = this[i] - this[i] = this[j] - this[j] = copy - } -} - diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index dad4b1cdaa8..4994437842b 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -1856,6 +1856,64 @@ class ArraysTest { array.iterator().assertSorted { a, b -> comparator.compare(a, b) <= 0 } } + private inline fun testShuffle(array: T, shuffle: T.() -> Unit, toList: T.() -> List<*>) { + val original = array.toList() + array.shuffle() + val shuffled = array.toList() + assertNotEquals(original, shuffled) + assertEquals(original.groupBy { it }, shuffled.groupBy { it }) + } + + @Test + fun shuffle() { + val numbers = List(100) { it } + testShuffle(numbers.map(Int::toInt).toIntArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toLong).toLongArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toByte).toByteArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toShort).toShortArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toFloat).toFloatArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toDouble).toDoubleArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toChar).toCharArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map { it % 2 == 0 }.toBooleanArray(), { shuffle() }, { toList() }) + + testShuffle(numbers.map(Int::toUInt).toUIntArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toULong).toULongArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toUByte).toUByteArray(), { shuffle() }, { toList() }) + testShuffle(numbers.map(Int::toUShort).toUShortArray(), { shuffle() }, { toList() }) + + testShuffle(arrayOf(1, "x", null, Any(), 'a', 2u, 5.0), { shuffle() }, { toList() }) + } + + private inline fun testShuffleR(array: T, shuffle: T.(Random) -> Unit, toList: T.() -> List<*>) { + val seed = Random.nextInt() + val original = array.toList() + val originalShuffled = original.shuffled(Random(seed)) + array.shuffle(Random(seed)) + val shuffled = array.toList() + assertNotEquals(original, shuffled) + assertEquals(originalShuffled, shuffled) + } + + @Test + fun shufflePredictably() { + val numbers = List(16) { it } + testShuffleR(numbers.map(Int::toInt).toIntArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toLong).toLongArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toByte).toByteArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toShort).toShortArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toFloat).toFloatArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toDouble).toDoubleArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toChar).toCharArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map { it % 2 == 0 }.toBooleanArray(), { r -> shuffle(r) }, { toList() }) + + testShuffleR(numbers.map(Int::toUInt).toUIntArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toULong).toULongArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toUByte).toUByteArray(), { r -> shuffle(r) }, { toList() }) + testShuffleR(numbers.map(Int::toUShort).toUShortArray(), { r -> shuffle(r) }, { toList() }) + + testShuffleR(arrayOf(1, "x", null, Any(), 'a', 2u, 5.0), { r -> shuffle(r) }, { toList() }) + } + @Test fun elementAt() { expect(0) { byteArrayOf(0, 1, 2).elementAt(0) } diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt index 2455e8fac4b..63d8cd63182 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt @@ -1577,6 +1577,24 @@ public final class kotlin/collections/ArraysKt { public static final fun scanIndexed ([Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; public static final fun scanReduce ([Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static final fun scanReduceIndexed ([Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; + public static final fun shuffle ([B)V + public static final fun shuffle ([BLkotlin/random/Random;)V + public static final fun shuffle ([C)V + public static final fun shuffle ([CLkotlin/random/Random;)V + public static final fun shuffle ([D)V + public static final fun shuffle ([DLkotlin/random/Random;)V + public static final fun shuffle ([F)V + public static final fun shuffle ([FLkotlin/random/Random;)V + public static final fun shuffle ([I)V + public static final fun shuffle ([ILkotlin/random/Random;)V + public static final fun shuffle ([J)V + public static final fun shuffle ([JLkotlin/random/Random;)V + public static final fun shuffle ([Ljava/lang/Object;)V + public static final fun shuffle ([Ljava/lang/Object;Lkotlin/random/Random;)V + public static final fun shuffle ([S)V + public static final fun shuffle ([SLkotlin/random/Random;)V + public static final fun shuffle ([Z)V + public static final fun shuffle ([ZLkotlin/random/Random;)V public static final fun single ([B)B public static final fun single ([BLkotlin/jvm/functions/Function1;)B public static final fun single ([C)C @@ -2553,6 +2571,14 @@ public final class kotlin/collections/unsigned/UArraysKt { public static final fun reversed-GBYM_sE ([B)Ljava/util/List; public static final fun reversed-QwZRm1k ([J)Ljava/util/List; public static final fun reversed-rL5Bavg ([S)Ljava/util/List; + public static final fun shuffle--ajY-9A ([I)V + public static final fun shuffle-2D5oskM ([ILkotlin/random/Random;)V + public static final fun shuffle-GBYM_sE ([B)V + public static final fun shuffle-JzugnMA ([JLkotlin/random/Random;)V + public static final fun shuffle-QwZRm1k ([J)V + public static final fun shuffle-oSF2wD8 ([BLkotlin/random/Random;)V + public static final fun shuffle-rL5Bavg ([S)V + public static final fun shuffle-s5X_as8 ([SLkotlin/random/Random;)V public static final fun singleOrNull--ajY-9A ([I)Lkotlin/UInt; public static final fun singleOrNull-GBYM_sE ([B)Lkotlin/UByte; public static final fun singleOrNull-QwZRm1k ([J)Lkotlin/ULong; diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt index c48417826c3..2b5c49c548c 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -457,4 +457,57 @@ object Ordering : TemplateGroupBase() { } } + + val f_shuffle = fn("shuffle()") { + include(InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) + } builder { + since("1.4") + returns("Unit") + doc { + """ + Randomly shuffles elements in this ${f.collection} in-place. + """ + } + body { + "shuffle(Random)" + } + } + + val f_shuffleRandom = fn("shuffle(random: Random)") { + include(Lists, InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) + } builder { + since("1.4") + returns("Unit") + doc { + """ + Randomly shuffles elements in this ${f.collection} in-place using the specified [random] instance as the source of randomness. + + See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + """ + } + specialFor(Lists) { + since("1.3") + receiver("MutableList") + } + body { + """ + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + val copy = this[i] + this[i] = this[j] + this[j] = copy + } + """ + } + specialFor(Lists) { + body { + """ + for (i in lastIndex downTo 1) { + val j = random.nextInt(i + 1) + this[j] = this.set(i, this[j]) + } + """ + } + } + } }