diff --git a/term1/questions_1.pdf b/term1/questions_1.pdf new file mode 100644 index 0000000..4d288c6 Binary files /dev/null and b/term1/questions_1.pdf differ diff --git a/term1/seminar01_overload/01_myspace/myspace.cpp b/term1/seminar01_overload/01_myspace/myspace.cpp new file mode 100644 index 0000000..4d93679 --- /dev/null +++ b/term1/seminar01_overload/01_myspace/myspace.cpp @@ -0,0 +1,14 @@ +#include +using std::cout; + +namespace myspace { + void print_n_times(char str[], int n = 10) { + for (int i = 0; i < n; ++i) + cout << str; + } +} + +int main() { + char s[] = "nya\n"; + myspace::print_n_times(s); +} diff --git a/term1/seminar01_overload/02_cubev/cubev.cpp b/term1/seminar01_overload/02_cubev/cubev.cpp new file mode 100644 index 0000000..01de22e --- /dev/null +++ b/term1/seminar01_overload/02_cubev/cubev.cpp @@ -0,0 +1,11 @@ +#include +using std::cout, std::endl; + +int cubeV(int x) { + return x * x * x; +} + +int main() { + int x = 3; + cout << cubeV(x) << endl; +} diff --git a/term1/seminar01_overload/03_cuber/cuber.cpp b/term1/seminar01_overload/03_cuber/cuber.cpp new file mode 100644 index 0000000..9a61a0a --- /dev/null +++ b/term1/seminar01_overload/03_cuber/cuber.cpp @@ -0,0 +1,12 @@ +#include + +using std::cout, std::endl; + +int cubeR(int& x) { + return x * x * x; +} + +int main() { + int x = 3; + cout << cubeR(x) << endl; +} diff --git a/term1/seminar01_overload/04_count_letters/count_letters.cpp b/term1/seminar01_overload/04_count_letters/count_letters.cpp new file mode 100644 index 0000000..6bf0706 --- /dev/null +++ b/term1/seminar01_overload/04_count_letters/count_letters.cpp @@ -0,0 +1,26 @@ +#include +using std::cout, std::endl; + +void count_letters(char str[], int& n_letters, int& n_digits, int& n_other) { + while (*str) { + if (*str >= 'a' && *str <= 'z' || *str >= 'A' && *str <= 'Z') { + n_letters += 1; + } + else if (*str >= '0' && *str <= '9') { + n_digits += 1; + } + else { + n_other += 1; + } + str += 1; + } +} + +int main() { + int n_letters = 0, n_digits = 0, n_other = 0; + + char s[] = "1n!2y#3a$"; + count_letters(s, n_letters, n_digits, n_other); + + cout << "letters: " << n_letters << endl << "digits: " << n_digits << endl << "n_other: " << n_other << endl; +} diff --git a/term1/seminar01_overload/05_add_price/add_price.cpp b/term1/seminar01_overload/05_add_price/add_price.cpp new file mode 100644 index 0000000..37b5baa --- /dev/null +++ b/term1/seminar01_overload/05_add_price/add_price.cpp @@ -0,0 +1,20 @@ +#include + +using std::cout, std::endl; + +struct Book { + char title[100]; + int pages; + float price; +}; + +void addPrice(Book& b, float x) { + b.price += x; +} + +int main() { + Book b = {"One Hundred Years of Solitude", 456, 1200}; + float x = 15.6; + addPrice(b, x); + cout << b.price << endl; +} diff --git a/term1/seminar01_overload/06_is_expensive/is_expensive.cpp b/term1/seminar01_overload/06_is_expensive/is_expensive.cpp new file mode 100644 index 0000000..1d56ff1 --- /dev/null +++ b/term1/seminar01_overload/06_is_expensive/is_expensive.cpp @@ -0,0 +1,20 @@ +#include +using std::cout, std::endl; + +struct Book { + char title[100]; + int pages; + float price; +}; + +bool isExpensive(const Book& b) { + if (b.price > 1000) { + return true; + } + return false; +} + +int main() { + Book b = {"One Hundred Years of Solitude", 456, 1200}; + cout << isExpensive(b) << endl; +} diff --git a/term1/seminar01_overload/07_vector3f/main.cpp b/term1/seminar01_overload/07_vector3f/main.cpp new file mode 100644 index 0000000..bde4776 --- /dev/null +++ b/term1/seminar01_overload/07_vector3f/main.cpp @@ -0,0 +1,38 @@ +#include +#include "vector3f.h" +using namespace std; + +int main() { + Vector3f a = {1.0, 2.0, -2.0}; + Vector3f b = {4.0, -1.0, 3.0}; + cout << "a = " << a << endl << "b = " << b << endl; + cout << "a + b = " << a + b << endl; + cout << "a - b = " << a - b << endl; + + cout << "0.5 * a = " << 0.5 * a << endl; + cout << "a * 0.5 = " << a * 0.5 << endl; + + cout << "(a, b) = " << a * b << endl; + + cout << "a / 5 = " << a / 5 << endl; + + cout << "-a = " << -a << endl; + cout << "+a = " << +a << endl; + + cout << "a == b = " << (a == b) << endl; + cout << "a != b = " << (a != b) << endl; + + a += b; + cout << "a += b: " << a << endl; + + a -= b; + cout << "a -= b: " << a << endl; + + a *= 2; + cout << "a *= 2: " << a << endl; + a /= 2; + cout << "a /= 2: " << a << endl; + + normalize(a); + cout << "normalize(a): " << a << " |a| = " << norm(a) << endl; +} diff --git a/term1/seminar01_overload/07_vector3f/vector3f.h b/term1/seminar01_overload/07_vector3f/vector3f.h new file mode 100644 index 0000000..36ce62f --- /dev/null +++ b/term1/seminar01_overload/07_vector3f/vector3f.h @@ -0,0 +1,96 @@ +#pragma once +#include +#include + +struct Vector3f { + float x; + float y; + float z; +}; + +Vector3f operator+(const Vector3f& a, const Vector3f& b) { + Vector3f result = {a.x + b.x, a.y + b.y, a.z + b.z}; + return result; +} + +Vector3f operator-(const Vector3f& a, const Vector3f& b) { + Vector3f result = {a.x - b.x, a.y - b.y, a.z - b.z}; + return result; +} + +Vector3f operator*(const Vector3f& a, float f) { + Vector3f result = {f * a.x, f * a.y, f * a.z}; + return result; +} + +Vector3f operator*(float f, const Vector3f& a) { + Vector3f result = {f * a.x, f * a.y, f * a.z}; + return result; +} + +int operator*(const Vector3f& a, const Vector3f& b) { + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +Vector3f operator/(const Vector3f& a, float f) { + Vector3f result = {a.x / f, a.y / f, a.z / f}; + return result; +} + +Vector3f operator+(const Vector3f& a) { + return a; +} + +Vector3f operator-(const Vector3f& a) { + Vector3f result = {-a.x, -a.y, -a.z}; + return result; +} + +bool operator==(const Vector3f& a, const Vector3f& b) { + if (a.x == b.x && a.y == b.y && a.z == b.z) { + return true; + } + return false; +} + +bool operator!=(const Vector3f& a, const Vector3f& b) { + return not (a == b); +} + +void operator+=(Vector3f& a, const Vector3f& b) { + a = a + b; +} + +void operator-=(Vector3f& a, const Vector3f& b) { + a = a - b; +} + +void operator*=(Vector3f& a, float f) { + a = f * a; +} + +void operator/=(Vector3f& a, float f) { + a = a / f; +} + +float squared_norm(const Vector3f& a) { + return a * a; +} + +float norm(const Vector3f& a) { + return sqrt(squared_norm(a)); +} + +void normalize(Vector3f& a) { + a /= norm(a); +} + +std::istream& operator>>(std::istream& in, Vector3f& a) { + in >> a.x >> a.y >> a.z; + return in; +} + +std::ostream& operator<<(std::ostream& out, const Vector3f& a) { + out << "(" << a.x << ", " << a.y << ", " << a.z << ")"; + return out; +} diff --git a/term1/seminar01_overload/08_complex/complex.h b/term1/seminar01_overload/08_complex/complex.h new file mode 100644 index 0000000..d1ea7a9 --- /dev/null +++ b/term1/seminar01_overload/08_complex/complex.h @@ -0,0 +1,189 @@ +#pragma once +#include +#include + +struct Complex { + float re; + float im; +}; + + +// Передаёмм аргументы через ссылки +// В данном случае можно было передавать по значению +// (так как Complex имеет малый размер) +// Но в общем случае лучше для структур лучше +// всегда использовать ссылки + +Complex operator+(const Complex& a, const Complex& b) { + Complex result = {a.re + b.re, a.im + b.im}; + return result; +} + +Complex operator-(const Complex& a, const Complex& b) { + Complex result = {a.re - b.re, a.im - b.im}; + return result; +} + +Complex operator*(const Complex& a, const Complex& b) { + Complex result = {a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re}; + return result; +} + +Complex operator/(const Complex& a, const Complex& b) { + float b_squared = b.re * b.re + b.im * b.im; + + Complex result; + result.re = (a.re * b.re + a.im * b.im) / b_squared; + result.im = (a.im * b.re - a.re * b.im) / b_squared; + return result; +} + +Complex& operator+=(Complex &a, const Complex &b) { + a.re += b.re; + a.im += b.im; + return a; +} + + +// Унарный оператор - +// То есть если z - комплексное число x + iy, то -z = - x - iy +Complex operator-(const Complex& a) { + Complex result; + result.re = -a.re; + result.im = -a.im; + return result; +} + +// Унарный оператор + +// Ничего не меняет +Complex operator+(const Complex& a) { + Complex result = a; + return result; +} + +// Унарный оператор * +// То есть если z - комплексное число x + iy, то *z = x - iy +// Оператор сопряжения +Complex operator*(const Complex& a) { + Complex result; + result.re = a.re; + result.im = -a.im; + return result; +} + + +// Число + комплексное число (в таком порядке) +Complex operator+(float a, const Complex& b) { + Complex result = b; + result.re += a; + return result; +} + +// Комплексное число + число +Complex operator+(const Complex& a, float b) { + Complex result = a; + result.re += b; + return result; +} + +// Число - комплексное число (в таком порядке) +Complex operator-(float a, const Complex& b) { + Complex result = -b; + result.re += a; + return result; +} + +// Комплексное число - число +Complex operator-(const Complex& a, float b) { + Complex result = a; + result.re -= b; + return result; +} + + + +// Комплексное число * число +Complex operator*(const Complex& a, float b) { + Complex result = a; + result.re *= b; + result.im *= b; + return result; +} + +// Число * комплексное число +Complex operator*(float a, const Complex& b) { + Complex result = b; + result.re *= a; + result.im *= a; + return result; +} + + +// Комплексное число / число +Complex operator/(const Complex& a, float b) { + Complex result = a; + result.re /= b; + result.im /= b; + return result; +} + +// Число / комплексное число +Complex operator/(float a, const Complex& b) { + float b_squared = b.re * b.re + b.im * b.im; + return (a * (*b)) / b_squared; +} + + +// Перегружаем оператор<< между типами +// std::ostream (такой тип имеет std::cout) и Complex +// Обратите внимание, что мы возвращаем ссылку на ostream +// Таким образом результатом выражения cout << a будет cout +// Поэтому можно делать так: cout << a << b << c ... +std::ostream& operator<<(std::ostream& out, const Complex& a) { + if (a.re != 0) + out << a.re; + + if (a.im > 0) { + if (a.im != 1.0) + out << " + " << a.im << "i"; + else + out << " + i"; + } + else if (a.im < 0) { + if (a.im != -1.0) + out << " - " << -a.im << "i"; + else + out << " - i"; + } + return out; +} + +std::istream& operator>>(std::istream& in, Complex& c) { + in >> c.re >> c.im; + return in; +} + +float abs(const Complex& a) { + return sqrtf(a.re * a.re + a.im * a.im); +} + +Complex exp(const Complex& a) { + Complex result; + result.re = expf(a.re) * cosf(a.im); + result.im = expf(a.re) * sinf(a.im); + return result; +} + +Complex sin(const Complex& a) { + Complex result; + result.re = sinf(a.re) * coshf(a.im); + result.im = cosf(a.re) * sinhf(a.im); + return result; +} + +Complex cos(const Complex& a) { + Complex result; + result.re = cosf(a.re) * coshf(a.im); + result.im = sinf(a.re) * sinhf(a.im); + return result; +} \ No newline at end of file diff --git a/term1/seminar01_overload/08_complex/complex_image.cpp b/term1/seminar01_overload/08_complex/complex_image.cpp new file mode 100644 index 0000000..f8b6166 --- /dev/null +++ b/term1/seminar01_overload/08_complex/complex_image.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include "complex.h" +using namespace std; + +// В этой программе мы рисуем в картинку комплексную функцию, +// которая задаётся в функции func + +struct Color { + unsigned char r, g, b; +}; + +Complex func(Complex z) { + Complex f = 100/(z - 1)*exp(z); + f.re = fabs(f.re); + f.im = fabs(f.im); + if (f.re > 255) + f.re = 255; + if (f.im > 255) + f.im = 255; + return f; +} + + +int main() { + int width = 800, height = 800; + float x0 = -2.0f, x1 = 2.0f; + float y0 = -2.0f, y1 = 2.0f; + + // Выделяем память под пиксели + Color* data = (Color*)malloc(sizeof(Color) * width * height); + + // data - это массив цветов размером width * height + // Задаём значения этого массива так, чтобы + // реальная часть функции func соответствовала зелёному цвету, + // а мнимая часть -- синей компоненте цвета + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + Complex z = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j}; + Complex f = func(z); + data[i + width * j].r = 0; + data[i + width * j].g = f.re; + data[i + width * j].b = f.im; + } + } + + // Сохраняем массив цветов data как картинку в формате .ppm + FILE* file = fopen("complex_image.ppm", "wb"); + fprintf(file, "P6\n%d %d\n255\n", width, height); + fwrite(data, sizeof(Color), height * width, file); + fclose(file); + + // Освобождаем память + free(data); +} \ No newline at end of file diff --git a/term1/seminar01_overload/08_complex/complex_movie.cpp b/term1/seminar01_overload/08_complex/complex_movie.cpp new file mode 100644 index 0000000..8470887 --- /dev/null +++ b/term1/seminar01_overload/08_complex/complex_movie.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include "complex.h" +using namespace std; + +// Это программа создаёт анимацию (набор картинок) +// которая задаётся как меняющееся во времени +// комплексная функция (описана в функции func) + + +struct Color { + unsigned char r, g, b; +}; + +Complex func(Complex z, int time) { + Complex f = 100/(z - (0.02f*time))*exp(z*sin(z)); + f.re = fabs(f.re); + f.im = fabs(f.im); + if (f.re > 255) + f.re = 255; + if (f.im > 255) + f.im = 255; + return f; +} + + +int main() { + int width = 800, height = 800; + float x0 = -2.0f, x1 = 2.0f; + float y0 = -2.0f, y1 = 2.0f; + Color* data = (Color*)malloc(sizeof(Color) * width * height); + + // Повторяем 200 раз + int max_time_steps = 200; + for (int time = 0; time < max_time_steps; time++) + { + // Задаём изображение в массиве data + for (int j = 0; j < height; j++) + { + for (int i = 0; i < width; i++) + { + Complex z = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j}; + Complex f = func(z, time); + data[i + width * j].r = 0; + data[i + width * j].g = f.re; + data[i + width * j].b = f.im; + } + } + + // Создаём в строке filename имя изображения + // Папка animation должна существовать! + char filename[100]; + sprintf(filename, "animation/complex_%03d.ppm", time); + + // Сохраняем изображение в картинке по имени filename + FILE* file = fopen(filename, "wb"); + fprintf(file, "P6\n%d %d\n255\n", width, height); + fwrite(data, sizeof(Color), height * width, file); + fclose(file); + } + free(data); +} \ No newline at end of file diff --git a/term1/seminar01_overload/08_complex/complex_movie.mp4 b/term1/seminar01_overload/08_complex/complex_movie.mp4 new file mode 100644 index 0000000..dbb775c Binary files /dev/null and b/term1/seminar01_overload/08_complex/complex_movie.mp4 differ diff --git a/term1/seminar01_overload/08_complex/complex_test.cpp b/term1/seminar01_overload/08_complex/complex_test.cpp new file mode 100644 index 0000000..6dd99c1 --- /dev/null +++ b/term1/seminar01_overload/08_complex/complex_test.cpp @@ -0,0 +1,38 @@ +#include +#include "complex.h" + +using namespace std; + +// Тут мы тестируем нашу реализацию комплексных чисел + +int main() { + Complex a; + Complex b; + + cin >> a >> b; + + cout << "a = " << a << endl + << "b = " << b << endl + << "a + b = " << a + b << endl + << "a - b = " << a - b << endl + << "a * b = " << a * b << endl + << "a / b = " << a / b << endl + << "-a = " << -a << endl + << "+a = " << +a << endl + << "*a = " << *a << endl + << "a + 5 = " << a + 5 << endl + << "5 + a = " << 5 + a << endl + << "a * 5 = " << a * 5 << endl + << "5 * a = " << 5 * a << endl + << "Exp(a) = " << exp(a) << endl + << "Sin(a) = " << sin(a) << endl + << "Cos(a) = " << cos(a) << endl + << "Exp((a + b) / a) * Cos(a - b) = " << exp((a + b) / a) * cos(a - b) << endl; + + a += b; + cout << "a += b; a = " << a << endl; + + // Оператор = мы не перегружали, но это всё равно работает + b = a; + cout << "b = a; b = " << b << endl; +} \ No newline at end of file diff --git a/term1/seminar01_overload/08_complex/julia.cpp b/term1/seminar01_overload/08_complex/julia.cpp new file mode 100644 index 0000000..9488592 --- /dev/null +++ b/term1/seminar01_overload/08_complex/julia.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include "complex.h" +using namespace std; + +struct Color { + unsigned char r, g, b; +}; + +Complex func(Complex z, Complex c) { + return z * z + c; +} + +int main(int argc, char** argv) { + Complex c = {0, 0}; + int n = 20; + int width = 800, height = 800; + float x0 = -2.0f, x1 = 2.0f; + float y0 = -2.0f, y1 = 2.0f; + + if (argc < 4) { + cout << "usage: julia [re] [im] [n]" << endl + << "using default values: 0 + 0i, n = 20 "<< endl; + } + else { + cout << argv[1] << " + " << argv[2] << "i" << endl << "n = " << n << endl; + sscanf(argv[1], "%f", &c.re); + sscanf(argv[2], "%f", &c.im); + sscanf(argv[3], "%d", &n); + } + + Color* data = (Color*)malloc(sizeof(Color) * width * height); + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + Complex z = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j}; + for (int k = 0; k < n; ++k) { + z = func(z, c); + } + + float r = abs(z.re); + float b = abs(z.im); + if (r > 255) { + r = 255; + } + if (b > 255) { + b = 255; + } + + data[i + width * j].r = 255 - r; + data[i + width * j].g = 0; + data[i + width * j].b = 255 - b; + } + } + + + FILE* file = fopen("julia.ppm", "wb"); + fprintf(file, "P6\n%d %d\n255\n", width, height); + fwrite(data, sizeof(Color), height * width, file); + fclose(file); + + free(data); +} diff --git a/term1/seminar01_overload/08_complex/julia_images/-0.4+0.6i.ppm b/term1/seminar01_overload/08_complex/julia_images/-0.4+0.6i.ppm new file mode 100644 index 0000000..5bbe88a Binary files /dev/null and b/term1/seminar01_overload/08_complex/julia_images/-0.4+0.6i.ppm differ diff --git a/term1/seminar01_overload/08_complex/julia_images/-0.7-0.38i.ppm b/term1/seminar01_overload/08_complex/julia_images/-0.7-0.38i.ppm new file mode 100644 index 0000000..5b6d46a Binary files /dev/null and b/term1/seminar01_overload/08_complex/julia_images/-0.7-0.38i.ppm differ diff --git a/term1/seminar01_overload/08_complex/julia_images/-0.8+0.16i.ppm b/term1/seminar01_overload/08_complex/julia_images/-0.8+0.16i.ppm new file mode 100644 index 0000000..e11cc0a Binary files /dev/null and b/term1/seminar01_overload/08_complex/julia_images/-0.8+0.16i.ppm differ diff --git a/term1/seminar01_overload/08_complex/julia_images/0.28+0.011i.ppm b/term1/seminar01_overload/08_complex/julia_images/0.28+0.011i.ppm new file mode 100644 index 0000000..510b0aa Binary files /dev/null and b/term1/seminar01_overload/08_complex/julia_images/0.28+0.011i.ppm differ diff --git a/term1/seminar01_overload/08_complex/julia_movie.cpp b/term1/seminar01_overload/08_complex/julia_movie.cpp new file mode 100644 index 0000000..fd5ba3a --- /dev/null +++ b/term1/seminar01_overload/08_complex/julia_movie.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include "complex.h" +using namespace std; + +struct Color { + unsigned char r, g, b; +}; + +Complex func(Complex z, Complex c) { + return z * z + c; +} + + +int main() { + int width = 800, height = 800; + float x0 = -2.0f, x1 = 2.0f; + float y0 = -2.0f, y1 = 2.0f; + int n = 20; + + Color* data = (Color*)malloc(sizeof(Color) * width * height); + + int max_time_steps = 500; + for (int time = 0; time < max_time_steps; time++) + { + Complex c = {-1.5 + (1.5 / max_time_steps) * time, -1.5 + (1.5 / max_time_steps) * time + 1}; + for (int j = 0; j < height; j++) + { + for (int i = 0; i < width; i++) + { + Complex z = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j}; + for (int k = 0; k < n; ++k) { + z = func(z, c); + } + + float r = abs(z.re); + float b = abs(z.im); + if (r > 255) { + r = 255; + } + if (b > 255) { + b = 255; + } + data[i + width * j].r = 255 - r; + data[i + width * j].g = 0; + data[i + width * j].b = 255 - b; + } + } + + char filename[100]; + sprintf(filename, "animation/complex_%03d.ppm", time); + + FILE* file = fopen(filename, "wb"); + fprintf(file, "P6\n%d %d\n255\n", width, height); + fwrite(data, sizeof(Color), height * width, file); + fclose(file); + } + free(data); +} diff --git a/term1/seminar01_overload/08_complex/mandelbrot.cpp b/term1/seminar01_overload/08_complex/mandelbrot.cpp new file mode 100644 index 0000000..6e3eef0 --- /dev/null +++ b/term1/seminar01_overload/08_complex/mandelbrot.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include "complex.h" +using namespace std; + +struct Color { + unsigned char r, g, b; +}; + +Complex func(Complex z, Complex c) { + return z * z + c; +} + +int main(int argc, char** argv) { + int n = 20; + Complex z = {0, 0}; + int width = 800, height = 800; + float x0 = -2.0f, x1 = 2.0f; + float y0 = -2.0f, y1 = 2.0f; + + + Color* data = (Color*)malloc(sizeof(Color) * width * height); + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + z = {0, 0}; + Complex c = {x0 + (x1-x0) / width * i, y0 + (y1-y0) / width * j}; + for (int k = 0; k < n; ++k) { + z = func(z, c); + } + + float r = abs(z.re); + float b = abs(z.im); + if (r > 255) { + r = 255; + } + if (b > 255) { + b = 255; + } + data[i + width * j].r = 255 - r; + data[i + width * j].g = 0; + data[i + width * j].b = 255 - b; + } + } + + + FILE* file = fopen("mandelbrot.ppm", "wb"); + fprintf(file, "P6\n%d %d\n255\n", width, height); + fwrite(data, sizeof(Color), height * width, file); + fclose(file); + + free(data); +} diff --git a/term1/seminar01_overload/08_complex/mandelbrot_images/mandelbrot.ppm b/term1/seminar01_overload/08_complex/mandelbrot_images/mandelbrot.ppm new file mode 100644 index 0000000..6a21dce Binary files /dev/null and b/term1/seminar01_overload/08_complex/mandelbrot_images/mandelbrot.ppm differ diff --git a/term1/seminar01_overload/homework_overload.pdf b/term1/seminar01_overload/homework_overload.pdf new file mode 100644 index 0000000..f95dc88 Binary files /dev/null and b/term1/seminar01_overload/homework_overload.pdf differ diff --git a/term1/seminar02_encapsulation/0circle/circle.cpp b/term1/seminar02_encapsulation/0circle/circle.cpp new file mode 100644 index 0000000..89b4e78 --- /dev/null +++ b/term1/seminar02_encapsulation/0circle/circle.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include "circle.h" +#include "point.h" + +Circle::Circle(const Point& acenter, float aradius) { + mCenter = acenter; + mRadius = aradius; +} +Circle::Circle() { + mCenter = Point {0, 0}; + mRadius = 1; +} +Circle::Circle(const Circle& circle) { + mCenter = circle.mCenter; + mRadius = circle.mRadius; +} +Point Circle::getCenter() const { return mCenter; } +float Circle::getRadius() const { return mRadius; } + +void Circle::setCenter(const Point& p) { + mCenter = p; +} +void Circle::setRadius(float radius) { + mRadius = radius > 0 ? radius : 0; +} +float Circle::getArea() const { + return abs(mRadius * mRadius * M_PI); +} +float Circle::getDistance(const Point& p) { + return mCenter.distance(p) - mRadius; +} +bool Circle::isColliding(const Circle& c) const { + return (mCenter.distance(c.getCenter()) - (mRadius + c.getRadius()) > 0) ? false : true; +} +void Circle::move(const Point& p) { + mCenter = mCenter + p; +} diff --git a/term1/seminar02_encapsulation/0circle/circle.h b/term1/seminar02_encapsulation/0circle/circle.h new file mode 100644 index 0000000..d0bc7ee --- /dev/null +++ b/term1/seminar02_encapsulation/0circle/circle.h @@ -0,0 +1,23 @@ +#include "point.h" +class Circle +{ +private: + Point mCenter; + float mRadius; + +public: + Circle(const Point& acenter, float aradius); + Circle(); + Circle(const Circle& circle); + Point getCenter() const; + float getRadius() const; + + void setCenter(const Point& p); + void setRadius(float radius); + float getArea() const; + float getDistance(const Point& p); + bool isColliding(const Circle& c) const; + void move(const Point& p); +}; + + diff --git a/term1/seminar02_encapsulation/0circle/main.cpp b/term1/seminar02_encapsulation/0circle/main.cpp new file mode 100644 index 0000000..0535945 --- /dev/null +++ b/term1/seminar02_encapsulation/0circle/main.cpp @@ -0,0 +1,44 @@ +#include +#include "point.h" +#include "circle.h" + +using std::cout, std::endl; + + +int main() +{ + Point p = {7, -1}; + Point q = {-4, 2}; + cout << "Point p = " << p << endl; + cout << "Point q = " << q << endl; + cout << "p + q = " << p + q << endl; + + + Circle a {{4, 1}, 3}; + Circle b; + // b = a; + + cout << "Circle a: center: " << a.getCenter() << " radius: " << a.getRadius() << endl; + cout << "Circle b: center: " << b.getCenter() << " radius: " << b.getRadius() << endl; + + cout << "Area of a = " << a.getArea() << endl; + cout << "Distance from point p to circle a = " << a.getDistance(p) << endl; + + + + cout << "Collisions:" << endl; + if (a.isColliding(b)) + cout << "Yes, a is colliding b" << endl; + else + cout << "No, a isn't colliding b" << endl; + + + + cout << "Moving b by {1, 1}:" << endl; + b.move({1, 1}); + if (a.isColliding(b)) + cout << "Yes, a is colliding b" << endl; + else + cout << "No, a isn't colliding b" << endl; + +} diff --git a/term1/seminar02_encapsulation/0circle/point.cpp b/term1/seminar02_encapsulation/0circle/point.cpp new file mode 100644 index 0000000..634ac98 --- /dev/null +++ b/term1/seminar02_encapsulation/0circle/point.cpp @@ -0,0 +1,82 @@ +#include +#include + +#include "point.h" + + +Point::Point(float x, float y) +{ + mx = x; + my = y; +} + +Point::Point() +{ + mx = 0; + my = 0; +} + + +float Point::getX() const +{ + return mx; +} + +float Point::getY() const +{ + return my; +} + +void Point::setX(float x) +{ + mx = x; +} + +void Point::setY(float y) +{ + my = y; +} + +float Point::norm() const +{ + return std::sqrt(mx * mx + my * my); +} + +void Point::normalize() +{ + float pnorm = norm(); + mx /= pnorm; + my /= pnorm; +} + +float Point::distance(const Point& p) const +{ + return std::sqrt((p.mx - mx) * (p.mx - mx) + (p.my - my) * (p.my - my)); +} + +Point Point::operator+(const Point& right) const +{ + Point result = {mx + right.mx, my + right.my}; + return result; +} + +Point Point::operator*(float a) const +{ + Point result = {a * mx, a * my}; + return result; +} + + + + +Point operator*(float a, const Point& p) +{ + Point result = {a * p.mx, a * p.my}; + return result; +} + +std::ostream& operator<<(std::ostream& left, const Point& right) +{ + left << "(" << right.mx << ", " << right.my << ")"; + return left; +} \ No newline at end of file diff --git a/term1/seminar02_encapsulation/0circle/point.h b/term1/seminar02_encapsulation/0circle/point.h new file mode 100644 index 0000000..fb50aae --- /dev/null +++ b/term1/seminar02_encapsulation/0circle/point.h @@ -0,0 +1,37 @@ +#pragma once + +/* + Поля x и y сделаны приватными + Конкретно для этого класса их можно было сделать публичными + Так как пользователь всё-равно будет иметь доступ без ограничений к этим полям через геттеры и сеттеры + Но они сделаны приватными для образовательных целей +*/ + +class Point +{ +private: + float mx, my; + +public: + + Point(float x, float y); + Point(); + + float getX() const; + float getY() const; + void setX(float x); + void setY(float y); + + void normalize(); + float distance(const Point& p) const; + float norm() const; + Point operator+(const Point& right) const; + Point operator*(float a) const; + + + + friend Point operator*(float a, const Point& p); + friend std::ostream& operator<<(std::ostream& left, const Point& right); +}; + + diff --git a/term1/seminar02_encapsulation/1number/main.cpp b/term1/seminar02_encapsulation/1number/main.cpp new file mode 100644 index 0000000..c394d6f --- /dev/null +++ b/term1/seminar02_encapsulation/1number/main.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include "number.h" + +Number fib(int n) +{ + Number a = 0; // F0 + Number b = 1; // F1 + for (int i = 1; i <= n; ++i) { + if (i % 2) { + a += b; + } else { + b += a; + } + } + if (n % 2) { + return b; + } + return a; +} + +Number factorial(int n) +{ + Number result { + 1}; + for (int i = 2; i < n + 1; ++i) { + result = Number(i) * result; + } + return result; +} + +void grad(Number n) +{ + + std::cout << "n = " << n; + Number max = n; + unsigned long long int steps = 0; + while (n != Number(1)) { + if (n > max) { +#ifdef _DEBUG_COMP + std::cout << n << " is greater than " << max << std::endl; +#endif + max = n; + } + if (n.isEven()) { + n.div2(); + } else { + n = Number(3) * n + Number(1); + } +#ifdef _DEBUG_GRAD + if (steps > 100) { + std::cout << "break" << std::endl; + break; + } +#endif + ++steps; + } + std::cout << " steps = " << steps << " max = " << max << std::endl; +} + +int main() +{ + std::cout << "===FIB===" << std::endl; + std::cout << "F(1000) = " << fib(1000) << std::endl; + std::cout << "===FAC===" << std::endl; + std::cout << "1000! = " << factorial(1000) << std::endl; + std::cout << "===GRAD===" << std::endl; + grad(Number("7")); + grad(Number("256")); + grad(Number("1117065")); + grad(Number("4761963248413673697")); + grad(Number("90560792656972947582439785608972465789628974587264056284658721771")); +} diff --git a/term1/seminar02_encapsulation/1number/number.cpp b/term1/seminar02_encapsulation/1number/number.cpp new file mode 100644 index 0000000..666e55f --- /dev/null +++ b/term1/seminar02_encapsulation/1number/number.cpp @@ -0,0 +1,343 @@ +#include +#include +#include +#include "number.h" + +Number::Number(int a) +{ +#ifdef _DEBUG_CONSTRUCTOR + std::cout << "(Number constructor " << a << " -> "; +#endif + // Находим размер необходимой памяти под это число + int temp = a; + capacity = 0; + while (temp != 0) { + temp /= base; + capacity += 1; + } + + // Отдельно обрабатываем случай, когда число равно 0 + if (capacity == 0) + capacity = 1; + + // Выделяем память и записывем число a в массив data + // Например, число 12345678 представится в виде массива [78, 56, 34, 12] + + data = new char[capacity]; + + for (int i = 0; i < capacity; ++i) { + data[i] = a % base; + a /= base; + } + + // В данном случае размер будет равен вместимости + size = capacity; +#ifdef _DEBUG_CONSTRUCTOR + std::cout << *this << ")" << std::endl; +#endif +} + +// Конструктор по умолчанию +Number::Number():Number(0){} + +// Конструктор копирования +Number::Number(const Number & n) +{ + size = n.size; + capacity = n.capacity; + data = new char[capacity]; + for (int i = 0; i < size; i++) { + data[i] = n.data[i]; + } +} + +Number::Number(const char *str) +{ + int len = std::strlen(str); + size = (len + len % 2) / 2; + capacity = size; + data = new char[capacity]; + char buf[2]; + for (int i = 0; i < size; i++) { + buf[1] = str[len - 2 * i - 1]; + if (len - 2 * i - 1 > 0) { + buf[0] = str[len - 2 * i - 2]; + } else { + buf[0] = '0'; + } + data[i] = std::stoi(buf); + } +} + +Number::~Number() +{ + delete[]data; +} + +Number & Number::operator=(const Number & right) +{ + capacity = right.capacity; + size = right.size; + data = new char[capacity]; + for (int i = 0; i < size; i++) { + data[i] = right.data[i]; + } + return *this; +} + +Number Number::operator+(Number a) +{ +#ifdef _DEBUG_ADD + std::cout << "arg1=" << a << "capacity=" << a. + capacity << ",size=" << a.size << std::endl; + std::cout << "arg2=" << *this << "capacity=" << this-> + capacity << ",size=" << this->size << std::endl; + +#endif + Number result; + Number temp; + int i; + int carry = 0; + if (size < a.size) { + temp = *this; + *this = a; + a = temp; + } + result.capacity = size + 1; + //result.data = new char[capacity]; + result.data = (char *) calloc(result.capacity, sizeof(char)); + for (i = 0; i < a.size; ++i) { + result.data[i] = (data[i] + a.data[i] + carry) % base; + carry = (data[i] + a.data[i] + carry) / base; + } + for (; i < size; ++i) { + result.data[i] = (data[i] + carry) % base; + carry = (data[i] + carry) / base; + } + if (carry) { +#ifdef _DEBUG_ADD + std::cout << "applied carry" << std::endl; +#endif + result.data[i] = carry; + result.size = size + 1; + } else { + result.size = size; + } +#ifdef _DEBUG_ADD + std::cout << result << " capacity=" << result. + capacity << ",size=" << result.size << std::endl; +#endif + return result; +} + +void Number::operator+=(const Number & a) +{ + *this = *this + a; +} + +bool Number::isEven() const +{ + if (data[0] % 2) { + return false; + } + return true; +} + +Number Number::operator*(const Number & right) const +{ +#ifdef _DEBUG_MUL + std:: + cout << "arg1=" << *this << "(capacity=" << capacity << ",size=" << + size << ")" << " " << "arg2=" << right << "(capacity=" << right. + capacity << ",size=" << right.size << ")" << std::endl; +#endif + if (*this == Number("0") || right == Number("0")) + return Number("0"); + int i, j; + int temp; + Number result; + + result.capacity = capacity + right.capacity; + int *carry = (int *) std::calloc(result.capacity, sizeof(int)); + + result.data = (char *) calloc(result.capacity, sizeof(char)); +#ifdef _DEBUG_MUL + std::cout << "carry:[" << carry[0]; + for (int k = 1; k < result.capacity; ++k) { + std::cout << "," << carry[k]; + } + std::cout << "]" << std::endl; +#endif + for (i = 0; i < size; ++i) { + for (j = 0; j < right.size; ++j) { +#ifdef _DEBUG_MUL + std::cout << i + j << ":" << static_cast < + int >(result.data[i + j]) << " + " << static_cast < + int >(data[i]) << " * " << static_cast < + int >(right.data[j]) << " + " << carry[i + j] << std::endl; +#endif + temp = + (result.data[i + j] + data[i] * right.data[j] + + carry[i + j]); + result.data[i + j] = temp % base; + carry[i + j + 1] += temp / base; + carry[i + j] = 0; + + } + } +#ifdef _DEBUG_MUL + std::cout << "result before applying carry:" << result << std::endl; + std::cout << "carry:[" << carry[0]; + for (int k = 1; k < result.capacity; ++k) { + std::cout << "," << carry[k]; + } + std::cout << "]" << std::endl; +#endif + if (carry[i + j - 1]) { + result.data[i + j - 1] = carry[i + j - 1]; + result.size = i + j; + } else { + result.size = i + j - 1; + } + +#ifdef _DEBUG_MUL + std::cout << "before correcting capacity, result=" << result << std:: + endl; +#endif + // correcting capacity + /*char* temp_data = (char *)calloc(result.size, sizeof(char)); + for (i = 0; i < result.size; ++i) { + temp_data[i] = result.data[i]; + } + + free(result.data); + result.capacity = result.size; + result.data = (char*)calloc(result.size,sizeof(char)); + for (i = 0; i < result.size; ++i) { + result.data[i] = temp_data[i]; + } + + free(temp_data); */ + free(carry); +#ifdef _DEBUG_MUL + std::cout << "return value=" << result << "(capacity=" << result. + capacity << ",size=" << result. + size << ")" << std::endl << "======" << std::endl; +#endif + return result; +} + +void Number::operator*=(const Number & a) +{ + *this = *this * a; +} + +bool Number::operator==(const Number & a) const +{ + if (size != a.size) { + return false; + } + for (int i = 0; i < size; ++i) { + if (data[i] != a.data[i]) { + return false; + } + } + return true; +} + +bool Number::operator!=(const Number & a) const +{ + return not(*this == a); +} + +bool Number::operator>(const Number & a) const +{ +#ifdef _DEBUG_COMP + std:: + cout << "comp " << *this << "(size=" << size << ") and " << a << + "(size=" << a.size << ")" << std::endl; +#endif + if (size > a.size) { +#ifdef _DEBUG_COMP + std::cout << "size > a.size => true" << std::endl; +#endif + return true; + } + if (size < a.size) { +#ifdef _DEBUG_COMP + std::cout << "size < a.size => false" << std::endl; +#endif + return false; + } + for (int i = size - 1; i >= 0; --i) { + if (data[i] > a.data[i]) { + return true; +#ifdef _DEBUG_COMP + std::cout << static_cast < + int >(data[i]) << ">" << static_cast < + int >(a.data[i]) << std::endl; +#endif + } + if (data[i] < a.data[i]) { +#ifdef _DEBUG_COMP + std::cout << static_cast < + int >(data[i]) << "<" << static_cast < + int >(a.data[i]) << std::endl; +#endif + return false; + } + + } +#ifdef _DEBUG_COMP + std::cout << "using final false" << std::endl; +#endif + return false; +} + +bool Number::operator<(const Number & a) const +{ + return not(*this > a) and(*this != a); +} + +void Number::div2() +{ +#ifdef _DEBUG_DIV2 + std::cout << "n = " << *this << std::endl; +#endif + int carry = 0; + int temp; + for (int i = size - 1; i >= 0; --i) { + temp = data[i] + carry * base; + data[i] = temp / 2; + carry = temp % 2; + } + if (data[size - 1] == 0) { + --size; + } +#ifdef _DEBUG_DIV2 + std::cout << "unstripped result " << *this << std::endl; +#endif +} + + +std::ostream & operator<<(std::ostream & stream, const Number & right) +{ +#ifdef _DEBUG_COUT + stream << "["; + for (std::size_t i = 0; i < right.size; ++i) { + stream << static_cast < + int >(right.data[right.size - 2 - i]) << ","; + } + stream << "]"; +#else + // Печатаем самый большой разряд + stream << (int) right.data[right.size - 1]; + + // Печатаем остальные разряды с заполнением нулями до 2-х цифр + // setfill и setw это то же самое, что и в языке C спецификатор %02d + for (std::size_t i = 0; i < right.size - 1; ++i) + stream << std::setfill('0') << std::setw(2) << (int) right. + data[right.size - 2 - i]; +#endif + return stream; +} diff --git a/term1/seminar02_encapsulation/1number/number.h b/term1/seminar02_encapsulation/1number/number.h new file mode 100644 index 0000000..fb78011 --- /dev/null +++ b/term1/seminar02_encapsulation/1number/number.h @@ -0,0 +1,63 @@ +#pragma once +/* + Класс Number -- класс положительных больших чисел + + Большое число будет храниться в динамическом массиве data + Каждый элемент этого массива содержит разряд числа в 100-ричной системе счисления + (так как base = 100) + По сути, каждый элемент data хранит две цифры числа в десятичной записи + + Значение 100 для системы счисления выбрано как компромис между + эффективностью и удобством написания программы. + Если выбрать значения базы 10 - то программа будет не так эффективна по памяти + Если выбрать значения базы 256 (максимально эффективное использование памяти для типа char), + то алгоритм печати на экран сильно усложнится + В качестве альтернативы, можно было выбрать базу 1e9, + изменив при этом тип элементов c char на int + + capacity - размер массива data + size - сколько ячеек занимет число в массиве data + size <= capacity + + Для удобства разряды числа хранятся в обратном порядке + Например, число 12345678 соответствует массиву + data = {78, 56, 34, 12} + (это упрощает многие алгоритмы с такими числами) +*/ + +class Number { + private: + static const int base = 100; + std::size_t size; + std::size_t capacity; + char *data; + + public: + + Number(int a); + Number(); + // Конструктор копирования + Number(const Number & n); + Number(const char *str); + ~Number(); + Number & operator=(const Number & right); + + Number operator+(Number a); + void operator+=(const Number & a); + + bool isEven() const; + + Number operator*(const Number & right) const; + void operator*=(const Number & a); + + bool operator==(const Number & a) const; + bool operator!=(const Number & a) const; + bool operator>(const Number & a) const; + bool operator<(const Number & a) const; + void div2(); + + friend std::ostream & operator<<(std::ostream & stream, + const Number & right); +}; + +std::ostream & operator<<(std::ostream & stream, const Number & right); diff --git a/term1/seminar02_encapsulation/homework_encapsulation.pdf b/term1/seminar02_encapsulation/homework_encapsulation.pdf new file mode 100644 index 0000000..52c019a Binary files /dev/null and b/term1/seminar02_encapsulation/homework_encapsulation.pdf differ diff --git a/term1/seminar03_initialization/01_letter_case_switch/main.cpp b/term1/seminar03_initialization/01_letter_case_switch/main.cpp new file mode 100644 index 0000000..c866f8b --- /dev/null +++ b/term1/seminar03_initialization/01_letter_case_switch/main.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +using namespace std; + +string letter_case_switch(const string & str) +{ + string result = str; + if (str.size() == 0) + return result; + result[0] = + isupper(result[0]) ? tolower(result[0]) : toupper(result[0]); + return result; +} + +int main() +{ + string meow; + cin >> meow; + cout << letter_case_switch(meow) << endl; +} diff --git a/term1/seminar03_initialization/01_letter_case_switch/main.cpp~ b/term1/seminar03_initialization/01_letter_case_switch/main.cpp~ new file mode 100644 index 0000000..30f8ff4 --- /dev/null +++ b/term1/seminar03_initialization/01_letter_case_switch/main.cpp~ @@ -0,0 +1,19 @@ +#include +#include +#include + +using namespace std; + +string letter_case_switch(const string& str) { + string result = str; + if (str.size() == 0) + return result; + result[0] = isupper(result[0]) ? tolower(result[0]) : toupper(result[0]); + return result; +} + +int main() { + string meow; + cin >> meow; + cout << letter_case_switch(meow) << endl; +} diff --git a/term1/seminar03_initialization/02_repeat/a.out~ b/term1/seminar03_initialization/02_repeat/a.out~ new file mode 100644 index 0000000..7c4ca02 Binary files /dev/null and b/term1/seminar03_initialization/02_repeat/a.out~ differ diff --git a/term1/seminar03_initialization/02_repeat/main.cpp b/term1/seminar03_initialization/02_repeat/main.cpp new file mode 100644 index 0000000..480bd91 --- /dev/null +++ b/term1/seminar03_initialization/02_repeat/main.cpp @@ -0,0 +1,48 @@ +#include +#include +#include + +using namespace std; + +string repeat1(string_view s) +{ + return string { + s} + +string { + s}; +} + +void repeat2(string & s) +{ + s += s; +} + +void repeat3(string * s) +{ + *s += *s; +} + +string *repeat4(string_view s) +{ + string *result = new string; + *result = string { + s} +string { + s}; + return result; +} + +int main() +{ + string meow; + cin >> meow; + + cout << "test of repeat1:" << endl << repeat1(meow) << endl; + + repeat2(meow); + cout << "test of repeat2:" << endl << meow << endl; + + repeat3(&meow); + cout << "test of repeat3:" << endl << meow << endl; + + cout << "test of repeat4:" << endl << *repeat4(meow) << endl; +} diff --git a/term1/seminar03_initialization/02_repeat/main.cpp~ b/term1/seminar03_initialization/02_repeat/main.cpp~ new file mode 100644 index 0000000..0cbb9c9 --- /dev/null +++ b/term1/seminar03_initialization/02_repeat/main.cpp~ @@ -0,0 +1,38 @@ +#include +#include +#include + +using namespace std; + +string repeat1(string_view s) { + return string{s} + string{s}; +} + +void repeat2(string& s) { + s += s; +} + +void repeat3(string* s) { + *s += *s; +} + +string* repeat4(string_view s) { + string* result = new string; + *result = string{s} + string{s}; + return result; +} + +int main() { + string meow; + cin >> meow; + + cout << "test of repeat1:" << endl << repeat1(meow) << endl; + + repeat2(meow); + cout << "test of repeat2:" << endl << meow << endl; + + repeat3(&meow); + cout << "test of repeat3:" << endl << meow << endl; + + cout << "test of repeat4:" << endl << *repeat4(meow) << endl; +} diff --git a/term1/seminar03_initialization/03_string_multiplication/main.cpp b/term1/seminar03_initialization/03_string_multiplication/main.cpp new file mode 100644 index 0000000..f01e662 --- /dev/null +++ b/term1/seminar03_initialization/03_string_multiplication/main.cpp @@ -0,0 +1,24 @@ +#include +#include + +using namespace std; + +string operator*(const string str, int n) { + string result; + for (int i = 0; i < n; ++i) + result += str; + return result; +} + +string operator*(int n, const string str) { + string result; + for (int i = 0; i < n; ++i) + result += str; + return result; +} + +int main() { + string meow; + cin >> meow; + cout << 3 * meow << endl; +} diff --git a/term1/seminar03_initialization/04_truncate_to_dot/main.cpp b/term1/seminar03_initialization/04_truncate_to_dot/main.cpp new file mode 100644 index 0000000..468312c --- /dev/null +++ b/term1/seminar03_initialization/04_truncate_to_dot/main.cpp @@ -0,0 +1,22 @@ +#include +#include + +using namespace std; + +void truncateToDot(string& s) { + s.resize(s.find('.')); + s.shrink_to_fit(); +} + +int main() { + std::string a = "cat.dog.mouse.elephant.tiger.lion"; + std::string b = "wikipedia.org"; + std::string c = ".com"; + truncateToDot(a); + truncateToDot(b); + truncateToDot(c); + + cout << a << endl + << b << endl + << c << endl; +} diff --git a/term1/seminar03_initialization/05_string_sum/main.cpp b/term1/seminar03_initialization/05_string_sum/main.cpp new file mode 100644 index 0000000..8ffd497 --- /dev/null +++ b/term1/seminar03_initialization/05_string_sum/main.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +using namespace std; + +int string_sum(const string& str) { + int res = 0; + int x; + int n = str.size(); + int i = 0; + while (i < n) { + switch (str[i]) { + case '[': + case ',' : + sscanf((str.c_str()) + i + 1, "%d", &x); + res += x; + break; + case ']' : + return res; + case ' ': + break; + default: + break; + } + ++i; + } + return -1; +} + +int main() { + string meow; + getline(cin, meow); + cout << string_sum(meow) << endl; +} diff --git a/term1/seminar03_initialization/06_new/main.cpp b/term1/seminar03_initialization/06_new/main.cpp new file mode 100644 index 0000000..dce9e33 --- /dev/null +++ b/term1/seminar03_initialization/06_new/main.cpp @@ -0,0 +1,34 @@ +#include +#include +#include + +using namespace std; + +int main() { + int *x = new int{123}; + cout << *x << endl; + + string *str = new string{"Cats and Dogs"}; + cout << *str << endl; + + int *xs = new int[]{10, 20, 30, 40, 50}; + for (int i = 0; i < 5; ++i) + cout << xs[i] << " "; + cout << endl; + + string *strs = new string[]{"Cat", "Dog", "Mouse"}; + for (int i = 0; i < 3; ++i) + cout << strs[i] << " "; + cout << endl; + + string_view *str_views = new string_view[]{strs[0], strs[1], strs[2]}; + for (int i = 0; i < 3; ++i) + cout << str_views[i] << " "; + cout << endl; + + delete x; + delete str; + delete[] xs; + delete[] strs; + delete[] str_views; +} diff --git a/term1/seminar03_initialization/07_placement/main.cpp b/term1/seminar03_initialization/07_placement/main.cpp new file mode 100644 index 0000000..3516d15 --- /dev/null +++ b/term1/seminar03_initialization/07_placement/main.cpp @@ -0,0 +1,22 @@ +#include +#include "miptstring.cpp" + +using std::cout, std::endl; + +int main() { + mipt::String stack{"Cat"}; + cout << stack << endl; + + mipt::String* heap = new mipt::String{"Dog"}; + cout << *heap << endl; + + char *x = (char*)malloc(sizeof(mipt::String)); + mipt::String* px = new(x) mipt::String{"Elephant"}; + + cout << *px << endl; + + px->~String(); + free(px); + delete heap; + +} diff --git a/term1/seminar03_initialization/07_placement/miptstring.cpp b/term1/seminar03_initialization/07_placement/miptstring.cpp new file mode 100644 index 0000000..f7e324e --- /dev/null +++ b/term1/seminar03_initialization/07_placement/miptstring.cpp @@ -0,0 +1,215 @@ +#pragma once + +#include +#include + +namespace mipt{ + +class String +{ +private: + + std::size_t mSize {0}; + std::size_t mCapacity {0}; + char* mpData {nullptr}; + +public: + + String(const char* str) + { + std::size_t strSize = std::strlen(str); + resize(strSize); + std::memcpy(mpData, str, mSize); + + std::cout << "mipt::String Constructor (" << mpData << ")" << std::endl; + } + + String() : String("") {} + String(const String& s) : String(s.cStr()) {} + + String(std::size_t n, char a) + { + resize(n); + + for (std::size_t i = 0; i < mSize; ++i) + mpData[i] = a; + + std::cout << "mipt::String Constructor (" << mpData << ")" << std::endl; + } + + ~String() + { + std::cout << "mipt::String Destructor (" << mpData << ")" << std::endl; + delete [] mpData; + } + + void reserve(std::size_t capacity) + { + if (capacity <= mCapacity) + return; + + mCapacity = std::max(2 * mCapacity, capacity); + char* newData = new char[mCapacity]; // errorCheckedMalloc(mCapacity); + + if (mpData) + std::memcpy(newData, mpData, mSize + 1); + + delete [] mpData; + mpData = newData; + } + + + void resize(std::size_t size) + { + reserve(size + 1); + mSize = size; + mpData[mSize] = '\0'; + } + + + String& operator=(const String& right) + { + if (this == &right) + return *this; + + mSize = right.mSize; + resize(mSize); + + std::memcpy(mpData, right.mpData, mSize + 1); + + return *this; + } + + + String operator+(const String& b) + { + String result; + result.resize(mSize + b.mSize); + + std::memcpy(result.mpData, mpData, mSize); + std::memcpy(result.mpData + mSize, b.mpData, b.mSize); + result.mpData[result.mSize] = '\0'; + + return result; + } + + String& operator+=(const String& right) + { + *this = *this + right; + return *this; + } + + bool operator==(const String& right) const + { + if (mSize != right.mSize) + return false; + + std::size_t i = 0; + while (i < mSize && mpData[i] == right.mpData[i]) + i++; + + return i == mSize; + } + + bool operator<(const String& right) const + { + std::size_t i = 0; + while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) + i++; + + return mpData[i] < right.mpData[i]; + } + + bool operator<=(const String& right) const + { + std::size_t i = 0; + while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) + i++; + + return mpData[i] <= right.mpData[i]; + } + + bool operator!=(const String& right) const + { + return !(*this == right); + } + + bool operator>(const String& right) const + { + return !(*this <= right); + } + + bool operator>=(const String& right) const + { + return !(*this < right); + } + + char& operator[](std::size_t i) + { + return mpData[i]; + } + + const char& operator[](std::size_t i) const + { + return mpData[i]; + } + + char& at(std::size_t i) + { + if (i >= mSize) + throw std::out_of_range{"mipt::String::at: index >= this->size()"}; + return mpData[i]; + } + + const char& at(std::size_t i) const + { + if (i >= mSize) + throw std::out_of_range{"mipt::String::at: index >= this->size()"}; + return mpData[i]; + } + + void clear() + { + delete [] mpData; + + mSize = 0; + mCapacity = 1; + mpData = new char[mCapacity]; + mpData[0] = '\0'; + } + + void addCharacter(char c) + { + if (mSize + 1 == mCapacity) + reserve(2 * mCapacity); + + mpData[mSize] = c; + resize(mSize + 1); + } + + + std::size_t getSize() const {return mSize;} + std::size_t getCapacity() const {return mCapacity;} + const char* cStr() const {return mpData;} +}; + + +std::ostream& operator<<(std::ostream& out, const String& s) +{ + out << s.cStr(); + return out; +} + +std::istream& operator>>(std::istream& in, String& s) +{ + s.clear(); + while (true) + { + char x = in.get(); + if (std::isspace(x)) + break; + s.addCharacter(x); + } + return in; +} +} \ No newline at end of file diff --git a/term1/seminar03_initialization/08_stringview/main.cpp b/term1/seminar03_initialization/08_stringview/main.cpp new file mode 100644 index 0000000..beaa948 --- /dev/null +++ b/term1/seminar03_initialization/08_stringview/main.cpp @@ -0,0 +1,18 @@ +#include +#include "miptstring.h" +#include "miptstringview.h" +using namespace std; + +int main() { + mipt::String a = "abcd"; + mipt::String b = "abce"; + mipt::StringView av = a; + mipt::StringView bv = b; + //cout << (b < a) << endl; + //cout << (bv < av) << endl; + cout << av.substr(1,10) << endl; + av.remove_suffix(2); + cout << av << endl; + mipt::String meow = av; + cout << "sv to string: " << meow << endl; +} diff --git a/term1/seminar03_initialization/08_stringview/miptstring.cpp b/term1/seminar03_initialization/08_stringview/miptstring.cpp new file mode 100644 index 0000000..ef07c94 --- /dev/null +++ b/term1/seminar03_initialization/08_stringview/miptstring.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include "miptstring.h" +#include "miptstringview.h" +using std::cout, std::cin, std::endl, std::size_t; + +namespace mipt{ + +char* errorCheckedMalloc(size_t newCapacity) +{ + char* result = static_cast(std::malloc(newCapacity * sizeof(char))); + if (result == NULL) + { + cout << "Error! Out of memory" << endl; + std::exit(1); + } + return result; +} + +String::String(const char* str) +{ + size_t strSize = std::strlen(str); + resize(strSize); + std::memcpy(mpData, str, mSize); +} + +String::String() : String("") {} +String::String(const String& s) : String(s.cStr()) {} +String::String(const StringView& sv) { + mSize = sv.size(); + (*this).reserve(mSize); + for(int i = 0; i < mSize; ++i) + mpData[i] = sv[i]; + mpData[mSize] = '\0'; + +} + +String::String(size_t n, char a) +{ + resize(n); + + for (size_t i = 0; i < mSize; ++i) + mpData[i] = a; +} + +String::~String() +{ + std::free(mpData); +} + +void String::reserve(size_t capacity) +{ + if (capacity <= mCapacity) + return; + + mCapacity = std::max(2 * mCapacity, capacity); + char* newData = errorCheckedMalloc(mCapacity); + + if (mpData) + std::memcpy(newData, mpData, mSize + 1); + + std::free(mpData); + mpData = newData; +} + + +void String::resize(size_t size) +{ + reserve(size + 1); + mSize = size; + mpData[mSize] = '\0'; +} + + +String& String::operator=(const String& right) +{ + if (this == &right) + return *this; + + mSize = right.mSize; + resize(mSize); + + std::memcpy(mpData, right.mpData, mSize + 1); + + return *this; +} + + +String String::operator+(const String& b) +{ + String result; + result.resize(mSize + b.mSize); + + std::memcpy(result.mpData, mpData, mSize); + std::memcpy(result.mpData + mSize, b.mpData, b.mSize); + result.mpData[result.mSize] = '\0'; + + return result; +} + +String& String::operator+=(const String& right) +{ + *this = *this + right; + return *this; +} + +bool String::operator==(const String& right) const +{ + if (mSize != right.mSize) + return false; + + size_t i = 0; + while (i < mSize && mpData[i] == right.mpData[i]) + i++; + + return i == mSize; +} + +bool String::operator<(const String& right) const +{ + size_t i = 0; + while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) + i++; + + return mpData[i] < right.mpData[i]; +} + +bool String::operator<=(const String& right) const +{ + size_t i = 0; + while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) + i++; + + return mpData[i] <= right.mpData[i]; +} + +bool String::operator!=(const String& right) const +{ + return !(*this == right); +} + +bool String::operator>(const String& right) const +{ + return !(*this <= right); +} + +bool String::operator>=(const String& right) const +{ + return !(*this < right); +} + +char& String::operator[](size_t i) +{ + return mpData[i]; +} + +const char& String::operator[](size_t i) const +{ + return mpData[i]; +} + +char& String::at(size_t i) +{ + if (i >= mSize) + { + cout << "Error! Index is out of bounds." << endl; + } + return mpData[i]; +} + +void String::clear() +{ + std::free(mpData); + + mSize = 0; + mCapacity = 1; + mpData = errorCheckedMalloc(mCapacity); + mpData[0] = '\0'; +} + +void String::addCharacter(char c) +{ + if (mSize + 1 == mCapacity) + reserve(2 * mCapacity); + + mpData[mSize] = c; + resize(mSize + 1); +} + + +size_t String::getSize() const {return mSize;} +size_t String::getCapacity() const {return mCapacity;} +const char* String::cStr() const {return mpData;} + + + +std::ostream& operator<<(std::ostream& out, const String& s) +{ + out << s.cStr(); + return out; +} + +std::istream& operator>>(std::istream& in, String& s) +{ + s.clear(); + while (true) + { + char x = in.get(); + if (x == ' ' || x == '\n' || x == '\t') + break; + s.addCharacter(x); + } + return in; +} + +} diff --git a/term1/seminar03_initialization/08_stringview/miptstring.h b/term1/seminar03_initialization/08_stringview/miptstring.h new file mode 100644 index 0000000..7a6d37f --- /dev/null +++ b/term1/seminar03_initialization/08_stringview/miptstring.h @@ -0,0 +1,43 @@ +#pragma once +#include + +namespace mipt { + +class StringView; +class String +{ +private: + size_t mSize {0}; + size_t mCapacity {0}; + char* mpData {nullptr}; +public: + String(const char* str); + String(); + String(const String& s); + String(const mipt::StringView& sv); + String(size_t n, char a); + ~String(); + void reserve(size_t capacity); + void resize(size_t size); + String& operator=(const String& right); + String operator+(const String& b); + String& operator+=(const String& right); + bool operator==(const String& right) const; + bool operator<(const String& right) const; + bool operator<=(const String& right) const; + bool operator!=(const String& right) const; + bool operator>(const String& right) const; + bool operator>=(const String& right) const; + char& operator[](size_t i); + const char& operator[](size_t i) const; + char& at(size_t i); + void clear(); + void addCharacter(char c); + size_t getSize() const; + size_t getCapacity() const; + const char* cStr() const; +}; + +std::ostream& operator<<(std::ostream& out, const String& s); +std::istream& operator>>(std::istream& in, String& s); +} diff --git a/term1/seminar03_initialization/08_stringview/miptstringview.cpp b/term1/seminar03_initialization/08_stringview/miptstringview.cpp new file mode 100644 index 0000000..9d903b3 --- /dev/null +++ b/term1/seminar03_initialization/08_stringview/miptstringview.cpp @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include "miptstring.h" +#include "miptstringview.h" +using std::cout, std::cin, std::endl, std::size_t; + +namespace mipt { + + StringView::StringView() {; + mSize = 0; + mpData = nullptr; + } + StringView::StringView(const StringView& str) { + mSize = str.mSize; + mpData = str.mpData; + } + StringView::StringView(const mipt::String& s) { + mSize = s.getSize(); + mpData = s.cStr(); + } + StringView::StringView(const char* s) { + mpData = s; + mSize = strlen(s); + } + const char& StringView::at(size_t i) + { + if (i >= mSize) + { + throw std::out_of_range("Error! Index is out of bounds."); + std::exit(1); + } + return mpData[i]; + } + const char& StringView::operator[](size_t i) const + { + return mpData[i]; + } + bool StringView::operator<(const StringView& right) const + { + size_t i = 0; + while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) + i++; + + return mpData[i] < right.mpData[i]; + } + size_t StringView::size() const { + return mSize; + } + StringView StringView::substr(size_t pos, size_t count) { + if (pos > mSize) + throw std::out_of_range("Error! Index is out of bounds."); + if (pos + count > mSize) + count = mSize - pos; + StringView result; + result.mpData = mpData + pos; + result.mSize = count; + return result; + } + void StringView::remove_prefix(size_t n) { + mSize -= n; + } + void StringView::remove_suffix(size_t n) { + mSize -= n; + mpData += n; + } +/*std::ostream& StringView::operator<<(std::ostream& out, mipt::StringView sv) { + size_t size = sv.size(); + for (int i = 0; i < size; ++i) + out << sv[i]; + return out; +}*/ +std::ostream& operator<<(std::ostream& out, const mipt::StringView& sv) { + size_t size = sv.size(); + for (int i = 0; i < size; ++i) + out << sv[i]; + return out; +} +}; + diff --git a/term1/seminar03_initialization/08_stringview/miptstringview.h b/term1/seminar03_initialization/08_stringview/miptstringview.h new file mode 100644 index 0000000..3dfd7ac --- /dev/null +++ b/term1/seminar03_initialization/08_stringview/miptstringview.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace mipt { +class String; +class StringView +{ +private: + const char* mpData; + size_t mSize; +public: + StringView(); + StringView(const StringView& str); + StringView(const mipt::String& s); + StringView(const char* s); + const char& at(size_t i); + const char& operator[](size_t i) const; + bool operator<(const StringView& right) const; + size_t size() const; + StringView substr(size_t pos, size_t count); + void remove_prefix(size_t n); + void remove_suffix(size_t n); +}; + +std::ostream& operator<<(std::ostream& out, const StringView& sv); + +} diff --git a/term1/seminar03_initialization/homework_initialization.pdf b/term1/seminar03_initialization/homework_initialization.pdf new file mode 100644 index 0000000..8f84c91 Binary files /dev/null and b/term1/seminar03_initialization/homework_initialization.pdf differ diff --git a/term1/seminar04_templates/01_sum_even/main.cpp b/term1/seminar04_templates/01_sum_even/main.cpp new file mode 100644 index 0000000..badaefd --- /dev/null +++ b/term1/seminar04_templates/01_sum_even/main.cpp @@ -0,0 +1,18 @@ +#include +#include + +using std::cout, std::endl; + +int sumEven(const std::vector& v) { + int sum = 0; + size_t s = v.size(); + for (int i = 0; i < s; ++i) + if (v[i] % 2 == 0) + sum += v[i]; + return sum; +} + +int main() { + std::vector v {4, 8, 15, 16, 23, 42}; + cout << sumEven(v) << endl; +} diff --git a/term1/seminar04_templates/02_last_digits/main.cpp b/term1/seminar04_templates/02_last_digits/main.cpp new file mode 100644 index 0000000..87cd622 --- /dev/null +++ b/term1/seminar04_templates/02_last_digits/main.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +using std::cout, std::endl, std::vector, std::span; + +vector lastDigits1(const vector& v) { + vector result; + size_t size = v.size(); + for(int i = 0; i < size; ++i) { + result.push_back(v[i] % 10); + } + return result; +} +void lastDigits2(vector& v) { + size_t size = v.size(); + for(int i = 0; i < size; ++i) { + v[i] %= 10; + } +} + +void lastDigits3(vector* pv) { + size_t size = pv->size(); + for(int i = 0; i < size; ++i) + (*pv)[i] %= 10; +} + +void lastDigits4(span sp) { + size_t size = sp.size(); + for(int i = 0; i < size; ++i) + sp[i] %= 10; +} + +std::ostream& operator<<(std::ostream& out, const vector& v) { + cout << "["; + size_t size = v.size(); + for(int i = 0; i < size; ++i) + cout << v[i] << (i == size - 1 ? "]" : " "); + return out; +} + +int main() { + vector meow{1, 2, 3, 12, 45, 32,313123,3245}; + vector result1 = lastDigits1(meow); + cout << result1 << endl; + + vector result2 = meow; + lastDigits2(result2); + cout << result2 << endl; + + vector result3 = meow; + lastDigits3(&result3); + cout << result3 << endl; + + span sp = meow; + lastDigits4(sp); + cout << meow << endl; +} diff --git a/term1/seminar04_templates/03_factorization/main.cpp b/term1/seminar04_templates/03_factorization/main.cpp new file mode 100644 index 0000000..990b5eb --- /dev/null +++ b/term1/seminar04_templates/03_factorization/main.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +using std::cout, std::endl, std::pair, std::vector; + +vector> factorization(int n) { + if (n == 1) { + return vector>{{1, 1}}; + } + int d = 2; + int c; + vector> result; + + while(n != 1) { + c = 0; + while(n % d == 0) { + c++; + n /= d; + } + if (c) + result.push_back(pair{d, c}); + d++; + } + return result; +} + +std::ostream& operator<<(std::ostream& out, pair p) { + out << "{" << p.first << ", " << p.second << "}"; + return out; +} + +std::ostream& operator<<(std::ostream& out, vector> v) { + out << "{"; + size_t size = v.size(); + for(int i = 0; i < size; ++i) { + out << v[i] << (i == size - 1 ? "}" : ", "); + } + return out; +} + +int main() { + vector> res = factorization(60); + cout << res << endl; + res = factorization(626215995); + cout << res << endl; + res = factorization(107); + cout << res << endl; + res = factorization(1); + cout << res << endl; +} diff --git a/term1/seminar04_templates/04_time/main.cpp b/term1/seminar04_templates/04_time/main.cpp new file mode 100644 index 0000000..6f99c57 --- /dev/null +++ b/term1/seminar04_templates/04_time/main.cpp @@ -0,0 +1,27 @@ +#include +#include "time.h" +#include +#include +#include + +using std::cout, std::endl, std::string, std::string_view, std::vector; + +int main() +{ + string t1s = "23:59:59"; + string_view t1sv = t1s; + string t2s = "23:59:59"; + string_view t2sv = t2s; + + Time t1 = t1sv; + Time t2 = t2sv; + cout << t1 + t2 << endl; + + string tss = "23:59:59 23:59:59 23:59:59"; + string_view tssv = tss; + vector < Time > tsv = getTimesFromString(tss); + for (int i = 0, size = tsv.size(); i < size; ++i) { + cout << tsv[i] << endl; + } + cout << sumTimes(tsv) << endl; +} diff --git a/term1/seminar04_templates/04_time/time.cpp b/term1/seminar04_templates/04_time/time.cpp new file mode 100644 index 0000000..335fdea --- /dev/null +++ b/term1/seminar04_templates/04_time/time.cpp @@ -0,0 +1,78 @@ +#include "time.h" +#include +#include +#include + +using std::cout, std::endl, std::vector, std::string_view, std::string; + +Time::Time(int hours, int minutes, int seconds) +{ + mHours = hours; + mMinutes = minutes; + mSeconds = seconds; +} + +Time::Time(string_view s) +{ + string buf; + buf = s.substr(0, 2); + mHours = stoi(buf); + buf = s.substr(3, 2); + mMinutes = stoi(buf); + buf = s.substr(6, 2); + mSeconds = stoi(buf); +} + +Time::Time():Time(0, 0, 0) +{ +}; + +Time Time::operator+(Time b) const +{ + return Time((mHours + b.mHours + (mMinutes + b.mMinutes) / 60) % 24, + (mMinutes + b.mMinutes + + (mSeconds + b.mSeconds) / 60) % 60, + (mSeconds + b.mSeconds) % 60); +} + +int Time::hours() const +{ + return mHours; +} + +int Time::minutes() const +{ + return mMinutes; +} + +int Time::seconds() const +{ + return mSeconds; +} + +vector < Time > getTimesFromString(string_view s) +{ + vector < Time > res; + for (int i = 0, size = s.size(); i < size; i += 9) { + res.push_back(Time(s.substr(i, 9))); + } + return res; +} + +Time sumTimes(const vector < Time > &v) +{ + Time res; + for (int i = 0, size = v.size(); i < size; ++i) { + res = res + v[i]; + } + return res; +} + +std::ostream & operator<<(std::ostream & out, Time t) +{ + out << std::setw(2) << std::setfill('0') << t.mHours + << ":" + << std::setw(2) << std::setfill('0') << t.mMinutes + << ":" << std::setw(2) << std::setfill('0') << t.mSeconds; + return out; +} diff --git a/term1/seminar04_templates/04_time/time.h b/term1/seminar04_templates/04_time/time.h new file mode 100644 index 0000000..f419c72 --- /dev/null +++ b/term1/seminar04_templates/04_time/time.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include +#include + +using std::string_view, std::vector; + +class Time { +private: + int mHours = 0, mMinutes = 0, mSeconds = 0; +public: + Time(int hours, int minutes, int seconds); + Time(); + Time(string_view s); + Time operator+(Time b) const; + int hours() const; int minutes() const; int seconds() const; + friend std::ostream& operator<<(std::ostream& out, Time t); +}; + +Time sumTimes(const vector