math/rand/v2.Perm în Go

Returnează o permutare aleatorie a numerelor 0, 1, ..., n-1, ca slice nou de int.

Sintaxă
import "math/rand/v2"

func Perm(n int) []int

Ce face math/rand/v2.Perm

rand.Perm(n) creează un slice cu numerele de la 0 la n-1, fiecare o singură dată, în ordine aleatorie. Este util ca listă de indici amestecați: parcurgi un slice într-o ordine aleatorie fără să-l modifici.

Dacă vrei să amesteci direct elementele unui slice existent, rand.Shuffle este mai potrivit (nu mai creează un slice nou).

Parametri

Parametru Descriere
n Câte numere conține permutarea. Dacă este negativ, programul se oprește cu panic.

Ce returnează

Un []int nou, de lungime n.

Exemple

Exemplul 1: Ordinea de prezentare a proiectelor

package main

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

func main() {
    elevi := []string{"Ana", "Mihai", "Ioana", "Radu", "Elena"}
    fmt.Println(rand.Perm(5))
    for poz, i := range rand.Perm(len(elevi)) {
        fmt.Printf("%d. %s\n", poz+1, elevi[i])
    }
}

Rezultat posibil (diferă la fiecare rulare)

[1 2 3 4 0]
1. Ioana
2. Elena
3. Radu
4. Mihai
5. Ana

Exemplul 2: Fiecare număr apare o singură dată

Cu seed fix, permutarea este aceeași la fiecare rulare. După sortare obții mereu 0..n-1.

package main

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

func main() {
    r := rand.New(rand.NewPCG(5, 5))
    p := r.Perm(8)
    fmt.Println(p)
    slices.Sort(p)
    fmt.Println(p)
}

Rezultat

[6 4 5 7 0 1 3 2]
[0 1 2 3 4 5 6 7]

Greșeli frecvente

  • Generezi indici cu IntN într-o buclă și primești duplicate: o permutare garantează că fiecare indice apare exact o dată.

Comenzi înrudite

  • math/rand/v2.Shuffle: Amestecă aleatoriu n elemente, apelând funcția swap pentru a interschimba elementele i și j.
  • math/rand/v2.IntN: Returnează un număr întreg aleatoriu din intervalul [0, n): IntN pentru int, plus variantele Int32N, Int64N, UintN, Uint32N, Uint64N.