diff options
-rw-r--r-- | 5_1.c | 80 | ||||
-rw-r--r-- | 5_2.c | 44 | ||||
-rw-r--r-- | 5_3.c | 39 | ||||
-rw-r--r-- | 6_1.c | 3 | ||||
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | gen.c | 36 | ||||
-rw-r--r-- | matrix.c | 116 | ||||
-rw-r--r-- | matrix.h | 69 |
8 files changed, 39 insertions, 360 deletions
@@ -1,80 +0,0 @@ -#include <stdio.h> -#include <time.h> - -#include "matrix.h" - -#define RAND_CHUNK = 0x7FFFFFFF; - -enum optype { ADD, SUB, MUL, DIV, POW, NOP }; - -// #pragma - просто способ заткнуть компилятор, чтобы он не выдавал предупреждений -// делает lookup table для операции, основываясь на символе -// по сути выполняет роль dict() в питоне или std::unordered_map в C++ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Winitializer-overrides" -enum optype op_lookup[255] = { - [0 ... 254] = NOP, - ['+'] = ADD, - ['-'] = SUB, - ['*'] = MUL, - ['/'] = DIV, - ['^'] = POW, -}; -#pragma GCC diagnostic pop - -// исполняет операцию над матрицами -void inplace_matrix_op(struct matrix *restrict a, struct matrix const *b, const enum optype t) { - if (a->rows != b->rows || a->columns != b->columns) return; - for(usz i = 0; i < b->rows; ++i) { - for (usz j = 0; j < b->columns; ++j) { - switch (t) { - case ADD: a->data[i][j] += b->data[i][j]; break; - case SUB: a->data[i][j] -= b->data[i][j]; break; - case MUL: a->data[i][j] *= b->data[i][j]; break; - case DIV: a->data[i][j] /= b->data[i][j]; break; - case POW: a->data[i][j] = pow(a->data[i][j], b->data[i][j]); break; - case NOP: return; - } - } - } -} - -int main(void) { - srand(time(NULL)); - // выбираем размер матрицы -size_selection: - printf("Input the size of the matrixes (rows, columns) separated by a whitespace:\n"); - isz row, col; - scanf("%zu %zu", &row, &col); - if (row < 0 || col < 0) { - SKIP_INPUT; - goto size_selection; - } - // выбираем интервал для генерации случайных чисел -interval_selection: - SKIP_INPUT; - printf("Input the borders of the interval for generated values, separated by a whitespace:\n"); - double a, b; - if (scanf("%lf %lf", &a, &b) != 2) goto interval_selection; - // создаём матрицы - struct matrix A = matrix_new(row, col), B = matrix_new(row, col); - matrix_fill(&A, a, b); - matrix_fill(&B, a, b); - puts("A = "); matrix_print(&A); - puts("B = "); matrix_print(&B); - // выбираем, что с матрицами делать -op_selection: - SKIP_INPUT; - printf("Input the operation ( + - * / ^ ): "); - enum optype op = op_lookup[getchar()]; - if (op == NOP) goto op_selection; - // выполняем операцию - inplace_matrix_op(&A, &B, op); - puts("result:"); - matrix_print(&A); - // освобождаем память - matrix_free(A); - matrix_free(B); - // ;) - return 0; -} @@ -1,44 +0,0 @@ -#include <stdio.h> -#include <time.h> -#include "matrix.h" - -#define MRX_SZ 6 -#define add_func(name, func) \ - double name (double x){ \ - return func; \ - } - -add_func(x2, x*x) -add_func(x2_sinx, x2(sin(x))) -add_func(sqrtx_x2, sqrt(x) * x2(x)) -add_func(sqrt_sin_x2, sqrt(sin(x2(x)))) - -const func_t funcs[MRX_SZ] = { - x2, sin, sqrt, x2_sinx, sqrtx_x2, sqrt_sin_x2 -}; - -int main(void) { - srand(time(NULL)); - // выбираем интервал для генерации случайных чисел -interval_selection: - printf("Input the borders of the interval for generated values, separated by a whitespace:\n"); - double a, b; - if (scanf("%lf %lf", &a, &b) != 2) { - SKIP_INPUT; - goto interval_selection; - } - // создаём матрицы - struct matrix m = matrix_new(1, MRX_SZ); - matrix_fill(&m, a, b); - struct matrix f_mem = matrix_new(1, MRX_SZ); - struct fmatrix f = *(struct fmatrix*)&f_mem; - for (usz i = 0; i < f.columns; ++i) f.funcs[0][i] = funcs[i]; - // делаем грязную работу - puts("A = "); matrix_print(&m); - matrix_apply(&m, &f); - puts("f(A) = "); matrix_print(&m); - // очищаем память - matrix_free(m); - matrix_free(f_mem); - return 0; -} @@ -1,39 +0,0 @@ -#include <stdio.h> -#include <time.h> - -#include "matrix.h" - -int main(void) { - srand(time(NULL)); - // выбираем размер матрицы -size_selection: - printf("Input the size of the matrixes:\n"); - isz size; - scanf("%zu", &size); - if (size < 0) { - SKIP_INPUT; - goto size_selection; - } - // выбираем интервал для генерации случайных чисел -interval_selection: - SKIP_INPUT; - printf("Input the borders of the interval for generated values, separated by a whitespace:\n"); - double a, b; - if (scanf("%lf %lf", &a, &b) != 2) goto interval_selection; - // создаём матрицы - struct tumatrix A = tumatrix_new(size); - struct tumatrix B = tumatrix_new(size); - tumatrix_fill(&A, a, b); - tumatrix_fill(&B, a, b); - puts("A = "); tumatrix_print(&A); - puts("B = "); tumatrix_print(&B); - printf("det A = %lf\n", tumatrix_det(&A)); - printf("det B = %lf\n", tumatrix_det(&B)); - struct tumatrix C = tumatrix_mul(&A, &B); - puts("C = A*B = "); tumatrix_print(&C); - printf("det C = %lf\n", tumatrix_det(&C)); - tumatrix_free(A); - tumatrix_free(B); - tumatrix_free(C); - return 0; -} @@ -0,0 +1,3 @@ +#include <stdio.h> +#include <string.h> + @@ -1,13 +1 @@ -# файлы -`5_1.c`, `5_2.c`, `5_3.c` - файлы для заданий 1, 2, 3 cоответственно -`matrix.c`, `matrix.h` - файлы со всеми алгоритмами и логикой - -# структура -каждый файл `5_*` содержит в себе только main и, может быть, вспомогательную функцию, и отвечает только за ввод/вывод. -Эти файлы имеют строчку `#include "matrix.h"`, и вызывают функции оттуда. Чтобы разобраться, что есть что в файле matrix.h, -есть 1: комментарии, 2: исходники для заданий (можно посмотреть, какое задание вызывает какие функции). - -# запуск -программы работают на любой платформе под компиляторами gcc и clang. MSVC (компилятор в visual studio) не проверял, он может -пожаловаться на `5_1.c`. Остальное должно работать без проблем. @@ -0,0 +1,36 @@ +#include <stdlib.h> +#include <stdio.h> + +int main(int argc, char *argv[]) { + srand(69420); + if (argc != 3) { + fputs("Error: usage: provide number of arguments and outpit filename\n" + "./a.out 69 amogus\n", stderr); + return 1; + } + int amount = atoi(argv[1]); + FILE *f = fopen(argv[2], "w+"); + fprintf(f, "Группа N%u\n", rand()); + fputs("Ф\tИ\tО\tг.р.\tФизика\tМатан\tИнф-ка\n", f); + for (int i = 0; i < amount; ++i) { + char lname[8] = {0}, + name[8] = {0}, + mname[8] = {0}; + int byear = rand()%125+1900, + scphy = rand() % 5 + 1, + scmat = rand() % 5 + 1, + scinf = rand() % 5 + 1; + lname[0] = rand() % ('Z'-'A'+1)+'A'; + name[0] = rand() % ('Z'-'A'+1)+'A'; + mname[0] = rand() % ('Z'-'A'+1)+'A'; + for (int j = 1; j < 7; ++j) { + lname[j] = rand() % ('z'-'a'+1)+'a'; + name[j] = rand() % ('z'-'a'+1)+'a'; + mname[j] = rand() % ('z'-'a'+1)+'a'; + } + fprintf(f, "%s\t%s\t%s\t%i\t%i\t%i\t%i\n", + lname, name, mname, + byear, scphy, scmat, scinf); + } + fclose(f); +} diff --git a/matrix.c b/matrix.c deleted file mode 100644 index 29c4457..0000000 --- a/matrix.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "matrix.h" - -// Почему так? Числа более рандомные получаются. А ещё это быстро. -double frand(double min, double max) { - double ret = 0; - unsigned long *ret_mem = (unsigned long*)&ret; - *ret_mem = ( ((unsigned long)rand() << 21) - ^ (unsigned long)rand() - ) & ~(1UL << 63); - int expa, expb; - frexp(min, &expa); - frexp(max, &expb); - int _exp = rand() % (expb-expa + 2) + expa - 1 ; - *ret_mem |= ((unsigned long)abs(_exp) << 52) | - (_exp < 0 ? 0UL << 62 : 1UL << 62); - return fmod(ret, max-min) + min; -} - -struct matrix matrix_new(usz rows, usz columns) { - double ** data = malloc(rows * sizeof (double*)); - for (usz i = 0; i < rows; ++i) - data[i] = malloc(columns * sizeof (double)); - return (struct matrix) { - .data = data, - .rows = rows, - .columns = columns, - }; -} - -void matrix_free(struct matrix m) { - for (usz i = 0; i < m.rows; ++i) - free(m.data[i]); - free(m.data); -} - -void matrix_print(struct matrix *m) { - for (usz i = 0; i < m->rows; ++i) { - printf("| "); - for (usz j = 0; j < m->columns; ++j) { - printf("%10.3g ", m->data[i][j]); - } - printf("|\n"); - } -} - -void matrix_fill(struct matrix *m, double min, double max) { - for (usz i = 0; i < m->rows; ++i) - for (usz j = 0; j < m->columns; ++j) - m->data[i][j] = frand(min, max); -} - -void matrix_apply(struct matrix *m, const struct fmatrix *fm) { - if (m->rows != fm->rows || m->columns != fm->columns) return; - for (usz i = 0; i < fm->rows; ++i) - for (usz j = 0; j < fm->columns; ++j) - m->data[i][j] = (fm->funcs[i][j])(m->data[i][j]); -} - - -struct tumatrix tumatrix_new(usz size) { - double **data = malloc(sizeof (double*) * size); - for (usz i = 0; i < size; ++i) - data[i] = malloc(sizeof (double) * (size - i)); - return (struct tumatrix){.data = data, .size = size}; -} - -void tumatrix_free(struct tumatrix m) { - for (usz i = 0; i < m.size; ++i) - free(m.data[i]); - free(m.data); -} - -double tumatrix_at(const struct tumatrix *m, usz row, usz column) { - if (row > column) return 0.0; - return m->data[row][column - row]; -} - -struct tumatrix tumatrix_mul(const struct tumatrix *a, const struct tumatrix *b) { - if (a->size != b->size) return (struct tumatrix){0}; - struct tumatrix c = tumatrix_new(a->size); - for (usz i = 0; i < a->size; ++i) { - for(usz j = i; j < a->size; ++j) { - double psum = 0; - // maybe r should go from i to j instead, will see - for (usz r = 0; r < a->size; ++r) - psum += tumatrix_at(a, i, r) * tumatrix_at(b, r, j); - c.data[i][j-i] = psum; - } - } - return c; -} - -// Определитель треугольной матрицы равен произведению элементов её главной диагонали -// [https://ru.wikipedia.org/wiki/Треугольная_матрица] -double tumatrix_det(const struct tumatrix *m) { - double prod = 1.0; - for (usz i = 0; i < m->size; ++i) - prod *= tumatrix_at(m, i, i); - return prod; -} - -void tumatrix_fill(struct tumatrix *m, double min, double max) { - for (usz i = 0; i < m->size; ++i) - for (usz j = 0; j < m->size - i; ++j) - m->data[i][j] = frand(min, max); -} - -void tumatrix_print(const struct tumatrix *m) { - for (usz i = 0; i < m->size; ++i) { - printf("| "); - for (usz j = 0; j < m->size; ++j) { - printf("%10.3g ", tumatrix_at(m, i, j)); - } - printf("|\n"); - } -} diff --git a/matrix.h b/matrix.h deleted file mode 100644 index 32f7da5..0000000 --- a/matrix.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef JAC_MATRIX_H -#define JAC_MATRIX_H - -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include <math.h> - -// Черная магия, чтобы сделать ввод более безопасным -#define SKIP_INPUT do { \ - int c; \ - do { c = getchar(); } \ - while (c != '\n' && c != EOF); \ -} while(0) - - -typedef size_t usz; -typedef ssize_t isz; - -typedef double(*func_t)(double); - -// матрица -struct matrix { - double **data; - usz rows, columns; -}; - -// матрица функций (Function MATRIX) -struct fmatrix { - func_t **funcs; - usz rows, columns; -}; - -// треугольная верхняя матрица. (Triangle Up MATRIX) -struct tumatrix { - double **data; - usz size; -}; - -// генерирует случайное число в диапазоне, используя внутреннее представление типа double в памяти -double frand(double min, double max); - -// создаёт матрицу -struct matrix matrix_new(usz rows, usz columns); -// удаляет матрицу -void matrix_free(struct matrix m); -// выводит матрицу -void matrix_print(struct matrix *m); -// заполняет матрицу случайными числами -void matrix_fill(struct matrix *m, double min, double max); -// поэлементно применяет функцию из fm на m -void matrix_apply(struct matrix *m, const struct fmatrix *fm); - -// создаёт новую треугольную матрицу -struct tumatrix tumatrix_new(usz size); -// удаляет треугольную матрицу -void tumatrix_free(struct tumatrix m); -// берёт i,j-ый элемент треугольной матрицы -double tumatrix_at(const struct tumatrix *m, usz row, usz column); -// умножает треугольные матрицы -struct tumatrix tumatrix_mul(const struct tumatrix *a, const struct tumatrix *b); -// определитель треугольной матрицы -double tumatrix_det(const struct tumatrix *m); -// заполняет треугольную матрицу -void tumatrix_fill(struct tumatrix *m, double min, double max); -// выводит треугольную матрицу на экран -void tumatrix_print(const struct tumatrix *m); - -#endif // JAC_MATRIX_H |