#include <cassert>
#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;
}