#include #include "Matrix.h" // REQUIRES: mat points to a Matrix // 0 < width && width <= MAX_MATRIX_WIDTH // 0 < height && height <= MAX_MATRIX_HEIGHT // MODIFIES: *mat // EFFECTS: Initializes *mat as a Matrix with the given width and height. // NOTE: Do NOT use new or delete here. void Matrix_init(Matrix* mat, int width, int height) { assert(0 < width && width <= MAX_MATRIX_WIDTH); assert(0 < height && height <= MAX_MATRIX_HEIGHT); mat->width = width; mat->height = height; mat->data[width * height] = {}; } // REQUIRES: mat points to a valid Matrix // MODIFIES: os // EFFECTS: First, prints the width and height for the Matrix to os: // WIDTH [space] HEIGHT [newline] // Then prints the rows of the Matrix to os with one row per line. // Each element is followed by a space and each row is followed // by a newline. This means there will be an "extra" space at // the end of each line. void Matrix_print(const Matrix* mat, std::ostream& os) { os << Matrix_width(mat) << " " << Matrix_height(mat) << std::endl; for (int r = 0; r < Matrix_height(mat); r++) { for (int c = 0; c < Matrix_width(mat); c++) { os << *Matrix_at(mat, r, c) << " "; } os << std::endl; } // for (int i = 0; i < (mat->width * mat->height); ++i) { // os << mat->data[i] << " "; // if ((i + 1) % mat->width == 0) { // os << std::endl; // } // } } // REQUIRES: mat points to an valid Matrix // EFFECTS: Returns the width of the Matrix. int Matrix_width(const Matrix* mat) { return mat->width; } // REQUIRES: mat points to a valid Matrix // EFFECTS: Returns the height of the Matrix. int Matrix_height(const Matrix* mat) { return mat->height; } // REQUIRES: mat points to a valid Matrix // ptr points to an element in the Matrix // EFFECTS: Returns the row of the element pointed to by ptr. int Matrix_row(const Matrix* mat, const int* ptr) { for (int r = 0; r < Matrix_height(mat); r++) { for (int c = 0; c < Matrix_width(mat); c++) { if (ptr == Matrix_at(mat, r, c)) { return r; } } } // for (int i = 0; i < (mat->width * mat->height); ++i) { // if (&(mat->data[i]) == ptr) { // return i / mat->width; // } // } // return 0; return 0; } // REQUIRES: mat points to a valid Matrix // ptr point to an element in the Matrix // EFFECTS: Returns the column of the element pointed to by ptr. int Matrix_column(const Matrix* mat, const int* ptr) { for (int r = 0; r < Matrix_height(mat); r++) { for (int c = 0; c < Matrix_width(mat); c++) { if (ptr == Matrix_at(mat, r, c)) { return c; } } } // for (int i = 0; i < (mat->width * mat->height); ++i) { // if (&(mat->data[i]) == ptr) { // return i % mat->width; // } // } // return 0; return 0; } // REQUIRES: mat points to a valid Matrix // 0 <= row && row < Matrix_height(mat) // 0 <= column && column < Matrix_width(mat) // // MODIFIES: (The returned pointer may be used to modify an // element in the Matrix.) // EFFECTS: Returns a pointer to the element in the Matrix // at the given row and column. int* Matrix_at(Matrix* mat, int row, int column) { assert(0 <= row && row < Matrix_height(mat)); assert(0 <= column && column < Matrix_width(mat)); int index = row * mat->width + column; int* ptr = &(mat->data[index]); return ptr; } // REQUIRES: mat points to a valid Matrix // 0 <= row && row < Matrix_height(mat) // 0 <= column && column < Matrix_width(mat) // // EFFECTS: Returns a pointer-to-const to the element in // the Matrix at the given row and column. const int* Matrix_at(const Matrix* mat, int row, int column) { assert(0 <= row && row < Matrix_height(mat)); assert(0 <= column && column < Matrix_width(mat)); int index = row * mat->width + column; const int* ptr = &(mat->data[index]); return ptr; } // REQUIRES: mat points to a valid Matrix // MODIFIES: *mat // EFFECTS: Sets each element of the Matrix to the given value. void Matrix_fill(Matrix* mat, int value) { for (int r = 0; r < Matrix_height(mat); r++) { for (int c = 0; c < Matrix_width(mat); c++) { *Matrix_at(mat, r, c) = value; } } // for (int i = 0; i < (mat->width * mat->height); ++i) { // mat->data[i] = value; // } } // REQUIRES: mat points to a valid Matrix // MODIFIES: *mat // EFFECTS: Sets each element on the border of the Matrix to // the given value. These are all elements in the first/last // row or the first/last column. void Matrix_fill_border(Matrix* mat, int value) { for (int r = 0; r < Matrix_height(mat); r++) { for (int c = 0; c < Matrix_width(mat); c++) { if (r == 0 || r == (Matrix_height(mat) - 1) || c == 0 || c == (Matrix_width(mat) - 1)) { *Matrix_at(mat, r, c) = value; } } } // for (int i = 0; i < (mat->width * mat->height); ++i) { // if (i < mat->width || i > ((mat->height - 1) * mat->width) - 1) { // mat->data[i] = value; // } // if (i % mat->width == 0 || (i + 1) % mat->width == 0) { // mat->data[i] = value; // } // } } // REQUIRES: mat points to a valid Matrix // EFFECTS: Returns the value of the maximum element in the Matrix int Matrix_max(const Matrix* mat) { int max = *Matrix_at(mat, 0, 0); for (int r = 0; r < Matrix_height(mat); r++) { for (int c = 0; c < Matrix_width(mat); c++) { if (*Matrix_at(mat, r, c) > max) { max = *Matrix_at(mat, r, c); } } } return max; // int max = mat->data[0]; // for (int i = 0; i < (mat->width * mat->height); ++i) { // if (mat->data[i] > max) { // max = mat->data[i]; // } // } // return max; } // REQUIRES: mat points to a valid Matrix // 0 <= row && row < Matrix_height(mat) // 0 <= column_start && column_end <= Matrix_width(mat) // column_start < column_end // EFFECTS: Returns the column of the element with the minimal value // in a particular region. The region is defined as elements // in the given row and between column_start (inclusive) and // column_end (exclusive). // If multiple elements are minimal, returns the column of // the leftmost one. int Matrix_column_of_min_value_in_row(const Matrix* mat, int row, int column_start, int column_end) { assert(0 <= row && row < Matrix_height(mat)); assert(0 <= column_start && column_end <= Matrix_width(mat)); assert(column_start < column_end); int min = *Matrix_at(mat, row, column_start); int min_index = column_start; for (int c = column_start; c < column_end; c++) { if (*Matrix_at(mat, row, c) < min) { min = *Matrix_at(mat, row, c); min_index = c; } } return min_index; // assert(0 <= row && row < mat->height); // assert(0 <= column_start && column_end <= mat->width); // // int start = (mat->width * row) + column_start; // int end = (mat->width * row) + column_end; // int min = mat->data[start]; // int min_index = start; // // for (int i = start; i <= end; ++i) { // if (mat->data[i] < min) { // min = mat->data[i]; // min_index = i; // } // } // return min_index - (mat->width * row); } // REQUIRES: mat points to a valid Matrix // 0 <= row && row < Matrix_height(mat) // 0 <= column_start && column_end <= Matrix_width(mat) // column_start < column_end // EFFECTS: Returns the minimal value in a particular region. The region // is defined as elements in the given row and between // column_start (inclusive) and column_end (exclusive). int Matrix_min_value_in_row(const Matrix* mat, int row, int column_start, int column_end) { assert(0 <= row && row < Matrix_height(mat)); assert(0 <= column_start && column_end <= Matrix_width(mat)); assert(column_start < column_end); int min = *Matrix_at(mat, row, column_start); for (int c = column_start; c < column_end; c++) { if (*Matrix_at(mat, row, c) < min) { min = *Matrix_at(mat, row, c); } } return min; // // int start = (mat->width * row) + column_start; // int end = (mat->width * row) + column_end; // int min = mat->data[start]; // // for (int i = start; i <= end; ++i) { // if (mat->data[i] < min) { // min = mat->data[i]; // } // } // return min; }