How to generate N random 1s in a zero-based matrix with Scala

1 Answer

0 votes
import scala.util.Random

/*
    Generate N random 1s in a zero-based matrix.

    Strategy:
    - Treat the matrix as a flat index space [0 until rows*cols].
    - Randomly pick unique positions using a Set to ensure uniqueness.
    - Convert each chosen flat index back to (row, col).
    - This avoids repeatedly searching for empty cells and keeps the logic simple.
*/

// Allocate a rows×cols matrix initialized to zero
def allocateMatrix(rows: Int, cols: Int): Array[Array[Int]] = {
  // Array.fill keeps the code compact and expressive
  Array.fill(rows, cols)(0)
}

// Print the matrix
def printMatrix(matrix: Array[Array[Int]]): Unit = {
  matrix.foreach { row =>
    println(row.mkString(" "))
  }
}

// Generate N random 1s in a zero-based matrix
def generateRandomMatrix(rows: Int, cols: Int, count: Int): Array[Array[Int]] = {
  val total: Int = rows * cols

  if (count > total)
    throw new IllegalArgumentException("Requested more 1s than available cells.")

  val matrix: Array[Array[Int]] = allocateMatrix(rows, cols)

  // Use a Set to ensure unique positions
  var chosen: Set[Int] = Set.empty

  val rng: Random = new Random()

  // Draw unique positions
  while (chosen.size < count) {
    val index: Int = rng.nextInt(total)
    chosen += index
  }

  // Convert flat indices to (row, col)
  chosen.foreach { index =>
    val r: Int = index / cols
    val c: Int = index % cols
    matrix(r)(c) = 1
  }

  matrix
}

// Example usage
@main def run(): Unit = {
  val rows: Int = 5
  val cols: Int = 7
  val numberOfOnes: Int = 10

  val result: Array[Array[Int]] = generateRandomMatrix(rows, cols, numberOfOnes)
  printMatrix(result)
}


/*
run:

0 0 1 0 1 0 0
0 0 0 1 1 1 1
0 0 0 1 0 0 0
0 0 1 0 0 0 1
0 0 0 0 0 1 0

*/

 



answered Aug 21 by avibootz
...