#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*
Select N unique random indices from an existing array.
Approach:
- Build an array of indices: 0, 1, 2, ..., size-1.
- Shuffle the indices using Fisher–Yates.
- Take the first N shuffled indices — guaranteed unique.
- Return those indices to the caller.
*/
// Shuffle an array of indices in-place using Fisher–Yates
void shuffle_indices(size_t *indices, size_t size) {
for (size_t i = size - 1; i > 0; --i) {
size_t j = (size_t)(rand() % (i + 1)); // random index in [0, i]
size_t tmp = indices[i];
indices[i] = indices[j];
indices[j] = tmp;
}
}
// Return N unique random indices
size_t *pick_unique_indices(size_t arr_size, size_t count) {
if (count > arr_size) {
fprintf(stderr, "Cannot pick more unique indices than array size.\n");
exit(EXIT_FAILURE);
}
// Allocate index list
size_t *indices = malloc(arr_size * sizeof(size_t));
if (!indices) {
fprintf(stderr, "Memory allocation failed.\n");
exit(EXIT_FAILURE);
}
// Fill with sequential indices
for (size_t i = 0; i < arr_size; ++i) {
indices[i] = i;
}
// Shuffle them
shuffle_indices(indices, arr_size);
// Allocate result array
size_t *result = malloc(count * sizeof(size_t));
if (!result) {
fprintf(stderr, "Memory allocation failed.\n");
free(indices);
exit(EXIT_FAILURE);
}
// Copy first N shuffled indices
for (size_t i = 0; i < count; ++i) {
result[i] = indices[i];
}
free(indices);
return result;
}
int main(void) {
// Example array
int data[] = {5, 12, 5, 19, 5, 33, 47, 5, 58, 61, 17, 3, 5, 74, 83, 90, 6};
size_t data_size = sizeof(data) / sizeof(data[0]);
// Number of unique indices to pick
size_t N = 6;
// Seed RNG once
srand((unsigned)time(NULL));
// Get unique random indices
size_t *indices = pick_unique_indices(data_size, N);
// Print results
printf("Random unique indices and their values:\n");
for (size_t i = 0; i < N; ++i) {
printf("index %zu -> value %d\n", indices[i], data[indices[i]]);
}
free(indices);
return 0;
}
/*
run:
Random unique indices and their values:
index 2 -> value 5
index 10 -> value 17
index 8 -> value 58
index 3 -> value 19
index 4 -> value 5
index 6 -> value 47
*/