use rand::rng;
use rand::seq::SliceRandom;
/// Generates a `rows` x `cols` matrix filled with zeros,
/// randomly placing `n` ones at unique positions.
fn generate_random_ones_matrix(rows: usize, cols: usize, n: usize) -> Vec<Vec<u8>> {
let total_elements = rows * cols;
// Guard against requesting more ones than available slots
assert!(
n <= total_elements,
"Cannot place {} ones in a matrix of size {}x{}",
n,
rows,
cols
);
// Initialize an empty matrix filled with zeros
let mut matrix = vec![vec![0u8; cols]; rows];
// Work with a 1D vector of all valid flat indices [0, total_elements)
let mut indices: Vec<usize> = (0..total_elements).collect();
// Acquire thread-local random number generator (rand 0.9+)
let mut rng = rng();
// Partial shuffle: pick `n` unique flat indices randomly in O(N) time
let (selected_indices, _) = indices.partial_shuffle(&mut rng, n);
// Map the selected 1D indices back to 2D matrix coordinates (row, col)
for flat_idx in selected_indices {
let row = *flat_idx / cols;
let col = *flat_idx % cols;
matrix[row][col] = 1;
}
matrix
}
fn main() {
let rows = 5;
let cols = 7;
let num_ones = 10;
let matrix = generate_random_ones_matrix(rows, cols, num_ones);
// Display the matrix output
for row in &matrix {
println!("{:?}", row);
}
}
/*
run:
[1, 0, 0, 1, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0]
[0, 1, 0, 1, 1, 0, 0]
[1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 1, 1, 0]
*/