aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSyndamia <kamen.d.mladenov@protonmail.com>2021-11-12 09:54:38 +0200
committerSyndamia <kamen.d.mladenov@protonmail.com>2021-11-12 09:54:38 +0200
commit072eaf227624e35e21b6a688d69478cc4af6feae (patch)
tree5bbfc18abf22114c50abc6b9dba31c0d62d964e5
parentdbaf69f0e0ede46cbf5765cb6ca9500fcd7a3ea7 (diff)
downloadalgorithms-072eaf227624e35e21b6a688d69478cc4af6feae.tar
algorithms-072eaf227624e35e21b6a688d69478cc4af6feae.tar.gz
algorithms-072eaf227624e35e21b6a688d69478cc4af6feae.zip
Added matrix calculator
-rw-r--r--C/MatrixCalculator.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/C/MatrixCalculator.c b/C/MatrixCalculator.c
new file mode 100644
index 0000000..ecd9370
--- /dev/null
+++ b/C/MatrixCalculator.c
@@ -0,0 +1,349 @@
+/*
+ * SCROLL TO BOTTOM FOR DOCUMENTATION
+ */
+
+#include <stdio.h> // printf, scanf
+#include <string.h> // strcspn, strtok
+#include <stdlib.h> // atoi, atof
+
+#define MAX_LINE_WIDTH 1024
+#define MATRIX_NUMBER_DELIMITER " "
+
+#define CMND_END "end"
+#define CMND_PRINT_MATRIX "print"
+#define CMND_PRINT_VARS "printv"
+#define CMND_SWAP_ROWS "swap"
+#define CMND_MULT_ROW "mult"
+#define CMND_DIV_ROW "div"
+#define CMND_SUM_ROW "sum"
+
+/* Matrix commands */
+void sumRows(char *command, int matrixRows, int matrixCols, double matrix[][matrixCols], int swapVars, double vars[][matrixCols]);
+void multRows(char *command, int matrixRows, int matrixCols, double matrix[][matrixCols], int swapVars, double vars[][matrixCols]);
+void divRows(char *command, int matrixRows, int matrixCols, double matrix[][matrixCols], int swapVars, double vars[][matrixCols]);
+void swapRows(char *command, int matrixRows, int matrixCols, double matrix[][matrixCols], int swapVars, double vars[][matrixCols]);
+
+/* Arrays */
+void assignArrValues(int cols, double arrDest[], double arrSrc[]);
+void multArrValues(int len, double arr[], double value);
+
+/* IO */
+void printMatrix(int mr, int mc, double matrix[][mc]);
+void inputToMatrix(char inputBuffer[], int matrixRows, int matrixCols, double matrix[][matrixCols]);
+void getInput(char inputBuffer[MAX_LINE_WIDTH]);
+
+
+int main() {
+ /*
+ * Get matricies
+ */
+
+ int rows, cols, hasVars;
+ scanf("%d %d %d\n", &rows, &cols, &hasVars);
+
+ double matrix[rows][cols];
+ double vars[rows][cols];
+
+ char inputBuffer[MAX_LINE_WIDTH];
+
+ inputToMatrix(inputBuffer, rows, cols, matrix);
+
+ if (hasVars)
+ inputToMatrix(inputBuffer, rows, cols, vars);
+
+ /*
+ * Modify matricies
+ */
+
+ printf("Commands:\n");
+
+ char *command;
+ do {
+ getInput(inputBuffer);
+ command = strtok(inputBuffer, MATRIX_NUMBER_DELIMITER);
+
+ if (!strcmp(inputBuffer, CMND_SWAP_ROWS))
+ swapRows(command, rows, cols, matrix, hasVars, vars);
+
+ else if (!strcmp(inputBuffer, CMND_MULT_ROW))
+ multRows(command, rows, cols, matrix, hasVars, vars);
+
+ else if (!strcmp(inputBuffer, CMND_DIV_ROW))
+ divRows(command, rows, cols, matrix, hasVars, vars);
+
+ else if (!strcmp(inputBuffer, CMND_SUM_ROW))
+ sumRows(command, rows, cols, matrix, hasVars, vars);
+
+ else if (!strcmp(inputBuffer, CMND_PRINT_MATRIX))
+ printMatrix(rows, cols, matrix);
+
+ else if (!strcmp(inputBuffer, CMND_PRINT_VARS))
+ printMatrix(rows, cols, vars);
+
+ } while (strcmp(inputBuffer, CMND_END) != 0);
+
+ /*
+ * End print
+ */
+
+ printMatrix(rows, cols, matrix);
+ if (hasVars)
+ printMatrix(rows, cols, vars);
+}
+
+/*
+ * Matrix commands
+ */
+
+void sumRows(char *command, int matrixRows, int matrixCols, double matrix[][matrixCols], int sumVars, double vars[][matrixCols]) {
+ /* Get input */
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ int rowSrc = atoi(command) - 1;
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ int rowDst = atoi(command) - 1;
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ double mult = atof(command);
+
+ double tmp[matrixCols];
+
+ /* Sum matrix rows */
+
+ assignArrValues(matrixCols, tmp, matrix[rowSrc]);
+ multArrValues(matrixCols, tmp, mult);
+
+ for (int i = 0; i < matrixCols; i++)
+ matrix[rowDst][i] += tmp[i];
+
+ /* Sum var rows */
+
+ if (sumVars) {
+ assignArrValues(matrixCols, tmp, vars[rowSrc]);
+ multArrValues(matrixCols, tmp, mult);
+
+ for (int i = 0; i < matrixCols; i++)
+ vars[rowDst][i] += tmp[i];
+ }
+}
+
+void multRows(char *command, int matrixRows, int matrixCols, double matrix[][matrixCols], int multVars, double vars[][matrixCols]) {
+ /* Get input */
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ int row = atoi(command) - 1;
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ double amount = atof(command);
+
+ /* Multiply matrix row */
+
+ multArrValues(matrixCols, matrix[row], amount);
+
+ /* Multiply var row */
+
+ if (multVars)
+ multArrValues(matrixCols, vars[row], amount);
+}
+
+void divRows(char *command, int matrixRows, int matrixCols, double matrix[][matrixCols], int divVars, double vars[][matrixCols]) {
+ /* Get input */
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ int row = atoi(command) - 1;
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ double amount = atof(command);
+
+ /* Divide matrix row */
+
+ multArrValues(matrixCols, matrix[row], 1.0/amount);
+
+ /* Divide var row */
+
+ if (divVars)
+ multArrValues(matrixCols, vars[row], 1.0/amount);
+}
+
+void swapRows(char *command, int matrixRows, int matrixCols, double matrix[][matrixCols], int swapVars, double vars[][matrixCols]) {
+ /* Get input */
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ int row1 = atoi(command) - 1;
+
+ command = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ int row2 = atoi(command) - 1;
+
+ double tmp[matrixCols];
+
+ /* Swap matrix rows */
+
+ assignArrValues(matrixCols, tmp, matrix[row1]);
+ assignArrValues(matrixCols, matrix[row1], matrix[row2]);
+ assignArrValues(matrixCols, matrix[row2], tmp);
+
+ /* Swap var rows */
+
+ if (swapVars) {
+ assignArrValues(matrixCols, tmp, vars[row1]);
+ assignArrValues(matrixCols, vars[row1], vars[row2]);
+ assignArrValues(matrixCols, vars[row2], tmp);
+ }
+}
+
+/*
+ * Arrays
+ */
+
+void assignArrValues(int len, double arrDest[], double arrSrc[]) {
+ for (int i = 0; i < len; i++)
+ arrDest[i] = arrSrc[i];
+}
+
+void multArrValues(int len, double arr[], double value) {
+ for (int i = 0; i < len; i++)
+ arr[i] *= value;
+}
+
+/*
+ * IO
+ */
+
+void printMatrix(int mr, int mc, double matrix[][mc]) {
+ for (int r = 0; r < mr; r++) {
+ /* Left bracket */
+
+ if (r == 0) printf("/");
+ else if (r == mr - 1) printf("\\");
+ else printf("|");
+
+ /* Middle values */
+
+ for (int c = 0; c < mc; c++)
+ printf(" %.3g ", matrix[r][c]);
+
+ /* Right bracket */
+
+ if (r == 0) printf("\\");
+ else if (r == mr - 1) printf("/");
+ else printf("|");
+ printf("\n");
+ }
+}
+
+void inputToMatrix(char inputBuffer[], int matrixRows, int matrixCols, double matrix[][matrixCols]) {
+ char *singleVal;
+ for (int r = 0; r < matrixRows; r++) {
+ /* Get input */
+
+ getInput(inputBuffer);
+ singleVal = strtok(inputBuffer, MATRIX_NUMBER_DELIMITER);
+
+ /* Assign input to matrix */
+
+ for (int c = 0; c < matrixCols; c++) {
+ matrix[r][c] = atof(singleVal);
+
+ singleVal = strtok(NULL, MATRIX_NUMBER_DELIMITER);
+ }
+ }
+}
+
+void getInput(char inputBuffer[MAX_LINE_WIDTH]) {
+ fgets(inputBuffer, MAX_LINE_WIDTH, stdin);
+ inputBuffer[strcspn(inputBuffer, "\n")] = 0; // Removes trailing \n
+}
+
+/* This is a small "calculator" for matricies. You type in the values of your matricies, then what actions to do with the rows and finally you'll get your calculated result.
+ * If your matrix uses variables alongside numbers, you can use the "var" matrix, which will calculate the result for each variable separately
+ *
+ * All inputs must be separated by spaces!
+ * First input should be three numbers: amount of rows, amount of columns and whether to use the var matrix (0 for "don't use it", anything else for "use it").
+ * After that you type in the values of your matricies, each number separated by a space and each line separated by a newline.
+ *
+ * All rows are indexed from 1! So, if you have 3 rows, the first one is at "index" 1 (index when typing in command)
+ *
+ * Then you can do the commands. There are 7 different ones in total:
+ * - end : ends the app (and prints the matricies)
+ * - print : prints the normal matrix
+ * - printv : prints the var matrix
+ * - swap <srcRow> <destRow> : swaps the values between two rows
+ * - mult <row> <multiplier> : multiplies a row by a given number (and saves that to the row)
+ * - div <row> divisor : divides a row by a given number (and saves that to the row)
+ * - sum <srcRow> <destRow> <srcMultiplier> : multiplies a row by a given number (without modifying it) and adds it to another row (sample usage: multiply first row by 1 and sum that to the 3rd row: sum 1 2 1)
+
+ * Sample usage (what gets typed and what gets outputted):
+ * (Stuff that are typed in by the use start with ** in the examples)
+ *
+ * I. No vars
+ *
+ * Matrix in task looks like:
+ * / 1 -1 0 -1 \
+ * | 2 -4 2 10 |
+ * \ -1 1 1 5 /
+ *
+** 3 4 0
+** 1 -1 0 -1
+** 2 -4 2 10
+** -1 1 1 5
+ * Commands:
+** div 2 2
+** swap 1 2
+** sum 1 2 -1
+** print
+ * / 1 -2 1 5 \
+ * | 0 1 -1 -6 |
+ * \ -1 1 1 5 /
+** sum 1 3 1
+** sum 2 3 1
+** end
+ * / 1 -2 1 5 \
+ * | 0 1 -1 -6 |
+ * \ 0 0 1 4 /
+ *
+ * (I'm too lazy to implement a system for aligning the numbers properly)
+ *
+ * I. With vars
+ *
+ * Matrix in task looks like:
+ * / 1 -1 0 -1 \
+ * | 2 -4 2*p 10*q |
+ * \ -1 1 1 5 /
+ *
+** 3 4 1
+** 1 -1 0 -1
+** 2 -4 2 10
+** -1 1 1 5
+** 0 0 0 0
+** 0 0 1 1
+** 0 0 0 0
+ * Commands:
+** div 2 2
+** swap 1 2
+** sum 1 2 -1
+** print
+ * / 1 -2 1 5 \
+ * | 0 1 -1 -6 |
+ * \ -1 1 1 5 /
+** printv
+ * / 0 0 0.5 0.5 \
+ * | 0 0 -0.5 -0.5 |
+ * \ 0 0 0 0 /
+** sum 1 3 1
+** sum 2 3 1
+** end
+ * / 1 -2 1 5 \
+ * | 0 1 -1 -6 |
+ * \ 0 0 1 4 /
+ * / 0 0 0.5 0.5 \
+ * | 0 0 -0.5 -0.5 |
+ * \ 0 0 0 0 /
+ *
+ * You'll have to add the first value from normal matrix to the value of var matrix * variable
+ * So, the proper result looks something like:
+ * / 1 -2 1+0.5*p 5+0.5*q \
+ * | 0 1 -1-0.5*p -6-0.5*q |
+ * \ 0 0 1 4 /
+ * (I'm too lazy to implement this type of printing)
+ */