/**
 * This function takes two matrices as input and returns their product.
 *
 * @param matrix1 The first matrix.
 * @param matrix2 The second matrix.
 * @return The product matrix.
 * @throws IllegalArgumentException If the dimensions of the matrices are incompatible for multiplication.
 *
 * Examples:
 * '``
 * val matrix1 = listOf(listOf(1, 2), listOf(3, 4))
 * val matrix2 = listOf(listOf(5, 6), listOf(7, 8))
 * multiplyMatrices(matrix1, matrix2) // Output: [[19, 22], [43, 50]]
 * '``
 */
fun multiplyMatrices(matrix1: List<List<Int>>, matrix2: List<List<Int>>): List<List<Int>> {

    if (matrix1[0].size != matrix2.size) {
        throw IllegalArgumentException("Incompatible dimensions for matrix multiplication!")
    }

    val result = mutableListOf<List<Int>>()
    for (row1 in matrix1) {
        val rowResult = mutableListOf<Int>()
        for (col2 in matrix2.transpose()) {
            val element = row1.zip(col2).sumBy { (a, b) -> a * b }
            rowResult.add(element)
        }
        result.add(rowResult)
    }

    return result
}

fun List<List<Int>>.transpose(): List<List<Int>> {
    return if (isEmpty() || this[0].isEmpty()) {
        emptyList()
    } else {
        (0 until this[0].size).map { col -> map { it[col] } }
    }
}
/**
 * This function takes two matrices as input and returns their product.
 *
 * @param matrix1 The first matrix.
 * @param matrix2 The second matrix.
 * @return The product matrix.
 * @throws IllegalArgumentException If the dimensions of the matrices are incompatible for multiplication.
 *
 * Examples:
 * '``
 * val matrix1 = listOf(listOf(1, 2), listOf(3, 4))
 * val matrix2 = listOf(listOf(5, 6), listOf(7, 8))
 * multiplyMatrices(matrix1, matrix2) // Output: [[19, 22], [43, 50]]
 * '``
 */
fun multiplyMatrices(matrix1: List<List<Int>>, matrix2: List<List<Int>>): List<List<Int>> {
/**
 * This function takes two matrices as input and returns their product.
 *
 * @param matrix1 The first matrix.
 * @param matrix2 The second matrix.
 * @return The product matrix.
 * @throws IllegalArgumentException If the dimensions of the matrices are incompatible for multiplication.
 *
 * Examples:
 * '``
 * val matrix1 = listOf(listOf(1, 2), listOf(3, 4))
 * val matrix2 = listOf(listOf(5, 6), listOf(7, 8))
 * multiplyMatrices(matrix1, matrix2) // Output: [[19, 22], [43, 50]]
 * '``
 */
fun multiplyMatrices(matrix1: List<List<Int>>, matrix2: List<List<Int>>): List<List<Int>> {

    if (matrix1[0].size != matrix2.size) {
        throw IllegalArgumentException("Incompatible dimensions for matrix multiplication!")
    }

    val result = mutableListOf<List<Int>>()
    for (row1 in matrix1) {
        val rowResult = mutableListOf<Int>()
        for (col2 in matrix2.transpose()) {
            val element = row1.zip(col2).sumBy { (a, b) -> a * b }
            rowResult.add(element)
        }
        result.add(rowResult)
    }

    return result
}

fun List<List<Int>>.transpose(): List<List<Int>> {
    return if (isEmpty() || this[0].isEmpty()) {
        emptyList()
    } else {
        (0 until this[0].size).map { col -> map { it[col] } }
    }
}