How to select N unique random values that appear exactly once in an existing slice with Go

1 Answer

0 votes
package main

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

/*
    Goal:
    - Select N random values that appear exactly once in the slice.
    - The slice includes duplicates, but only values with frequency = 1
      are eligible for selection.

    Approach:
    1. Count frequencies using a map[int]int.
    2. Collect values that appear exactly once.
    3. Shuffle the unique slice using rand.Shuffle.
    4. Take the first N values.
    5. Return them and print them.

    Notes:
    - Uses Go's built-in tools for clarity and efficiency.
    - Uses structured, expressive functions.
*/

//---------------------------------------------------------------
// Build a frequency map: value -> count
//---------------------------------------------------------------
func buildFrequencyMap(data []int) map[int]int {
    freq := make(map[int]int)

    for _, value := range data {
        freq[value]++
    }

    return freq
}

//---------------------------------------------------------------
// Collect values that appear exactly once
//---------------------------------------------------------------
func collectGloballyUniqueValues(data []int, freq map[int]int) []int {
    unique := make([]int, 0)

    for _, value := range data {
        if freq[value] == 1 {
            unique = append(unique, value)
        }
    }

    return unique
}

//---------------------------------------------------------------
// Randomly select N values from the unique slice
//---------------------------------------------------------------
func selectRandomUnique(unique []int, N int) []int {
    if N > len(unique) {
        N = len(unique) // clamp
    }

    // Shuffle using Fisher–Yates via rand.Shuffle
    temp := make([]int, len(unique))
    copy(temp, unique)

    rand.Shuffle(len(temp), func(i, j int) {
        temp[i], temp[j] = temp[j], temp[i]
    })

    return temp[:N]
}

//---------------------------------------------------------------
// Print helper
//---------------------------------------------------------------
func printSlice(slice []int) {
    for _, v := range slice {
        fmt.Printf("%d ", v)
    }
    fmt.Println()
}

//---------------------------------------------------------------
// Main program
//---------------------------------------------------------------
func main() {
    rand.Seed(time.Now().UnixNano())

    // Example slice with duplicates
    data := []int{
        5, 12, 5, 19, 5, 33, 19, 5, 8, 8, 8, 59, 61, 17, 3, 5, 3, 74, 83, 90, 3, 1,
    }

    // Step 1: Build frequency map
    freq := buildFrequencyMap(data)

    // Step 2: Collect values that appear exactly once
    uniqueValues := collectGloballyUniqueValues(data, freq)

    // Step 3: Choose how many unique random values to select
    N := 5

    // Step 4: Select N random unique values
    randomSelection := selectRandomUnique(uniqueValues, N)

    // Step 5: Print results
    fmt.Println("Values that appear exactly once:")
    printSlice(uniqueValues)

    fmt.Printf("\nRandom selection (%d values):\n", N)
    printSlice(randomSelection)
}



/*
run:

Values that appear exactly once:
12 33 59 61 17 74 83 90 1 

Random selection (5 values):
90 83 33 17 61 

*/

 



answered Sep 13 by avibootz

Related questions

...