math/rand/v2.Shuffle în Go

Amestecă aleatoriu n elemente, apelând funcția swap pentru a interschimba elementele i și j.

Sintaxă
import "math/rand/v2"

func Shuffle(n int, swap func(i, j int))

Ce face math/rand/v2.Shuffle

rand.Shuffle amestecă elementele unei colecții folosind algoritmul Fisher–Yates, care dă toate ordinile cu aceeași probabilitate. Funcția nu știe nimic despre slice-ul tău: îi dai numărul de elemente n și o funcție swap(i, j) care interschimbă elementele de pe pozițiile i și j.

De obicei funcția swap este func(i, j int) { s[i], s[j] = s[j], s[i] }. Amestecarea se face pe loc: slice-ul inițial este modificat.

Parametri

Parametru Descriere
n Numărul de elemente amestecate.
swap Funcția care interschimbă elementele i și j.

Ce returnează

Nimic; colecția este modificată pe loc.

Exemple

Exemplul 1: Amestecarea întrebărilor dintr-un test

package main

import (
    "fmt"
    "math/rand/v2"
)

func main() {
    intrebari := []string{"Capitala?", "Râul?", "Muntele?", "Anul?"}
    rand.Shuffle(len(intrebari), func(i, j int) {
        intrebari[i], intrebari[j] = intrebari[j], intrebari[i]
    })
    fmt.Println(intrebari)
}

Rezultat posibil (diferă la fiecare rulare)

[Râul? Muntele? Anul? Capitala?]

Exemplul 2: Împărțirea cărților, reproductibil

Un generator cu seed fix dă aceeași amestecare, util ca să repeți exact o partidă.

package main

import (
    "fmt"
    "math/rand/v2"
)

func main() {
    carti := []string{"A♠", "K♠", "Q♠", "J♠", "10♠", "9♠"}
    r := rand.New(rand.NewPCG(11, 22))
    r.Shuffle(len(carti), func(i, j int) { carti[i], carti[j] = carti[j], carti[i] })
    fmt.Println("Ana:  ", carti[:3])
    fmt.Println("Mihai:", carti[3:])
}

Rezultat

Ana:   [K♠ 9♠ 10♠]
Mihai: [J♠ Q♠ A♠]

Greșeli frecvente

  • Scrii o funcție swap care nu interschimbă de fapt (de exemplu s[i] = s[j]): elementele se duplică și altele se pierd.
  • Amesteci cu propria buclă s[i], s[rand.IntN(n)] pentru fiecare i: ordinea rezultată nu este uniformă. Folosește Shuffle.

Comenzi înrudite

  • math/rand/v2.Perm: Returnează o permutare aleatorie a numerelor 0, 1, …, n-1, ca slice nou de int.
  • math/rand/v2.IntN: Returnează un număr întreg aleatoriu din intervalul [0, n): IntN pentru int, plus variantele Int32N, Int64N, UintN, Uint32N, Uint64N.
  • slices.Reverse: Inversează ordinea elementelor unui slice, pe loc.