├── week-05 ├── README.md └── 01-Programming-Assignment │ └── Solution │ ├── README.md │ └── main.cpp ├── week-04 ├── 01-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── lecture_title.cpp │ └── README.md ├── W4P1.pdf ├── W4P2.pdf ├── W4P3.pdf ├── W4P4.pdf ├── main.pdf ├── README.md ├── 03-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── README.md │ └── invertible_function_with_mult.cpp ├── 10-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── rational_throw.cpp │ └── README.md ├── 06-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── README.md │ └── table.cpp ├── 04-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ ├── input.cpp │ │ └── output.cpp │ ├── input.cpp │ ├── output.cpp │ └── README.md ├── 09-Practice-Programming-Assignment │ ├── README.md │ └── ensure_equal.cpp ├── 05-Practice-Programming-Assignment │ ├── accuracy.cpp │ └── README.md ├── 12-Programming-Assignment │ ├── Solution │ │ └── main.cpp │ ├── Source │ │ └── time_server.cpp │ ├── time_server.cpp │ └── README.md ├── 08-Programming-Assignment │ ├── Source │ │ ├── rational_mult_div.cpp │ │ ├── rational_eq_add_sub.cpp │ │ ├── rational_map.cpp │ │ ├── rational_io.cpp │ │ └── rational_interface.cpp │ ├── rational_interface.cpp │ ├── rational_eq_add_sub.cpp │ ├── rational_mult_div.cpp │ ├── Solution │ │ └── main.cpp │ ├── rational_io.cpp │ ├── rational_map.cpp │ └── README.md ├── 11-Practice-Programming-Assignment │ ├── README.md │ └── rational_calc.cpp ├── 07-Practice-Programming-Assignment │ ├── README.md │ └── students.cpp └── 02-Practice-Programming-Assignment │ ├── README.md │ └── invertible_function.cpp ├── week-01 ├── W1P4.pdf ├── 03-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── equation.cpp │ └── README.md ├── 07-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── main.cpp │ └── README.md ├── 08-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── main.cpp │ └── README.md ├── README.md ├── 01-Programming-Assignment │ ├── main.cpp │ └── README.md ├── 02-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── main.cpp │ └── README.md ├── 04-Practice-Programming-Assignment │ ├── main.cpp │ └── README.md ├── 06-Practice-Programming-Assignment │ ├── main.cpp │ └── README.md ├── 09-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── main.cpp │ └── README.md └── 05-Practice-Programming-Assignment │ ├── main.cpp │ └── README.md ├── week-02 ├── W2P1.pdf ├── W2P2.pdf ├── 05-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── MoveStrings.cpp │ ├── MoveStrings.cpp │ └── README.md ├── README.md ├── 06-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── Reverse.cpp │ ├── Reverse.cpp │ └── README.md ├── 09-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── queue.cpp │ ├── queue.cpp │ └── README.md ├── 01-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── Factorial.cpp │ ├── Factorial.cpp │ └── README.md ├── 18-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── buses3.cpp │ ├── buses3.cpp │ └── README.md ├── 03-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── PalindromFilter.cpp │ ├── PalindromFilter.cpp │ └── README.md ├── 17-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── synonyms.cpp │ ├── synonyms.cpp │ └── README.md ├── 10-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── MonthlyBusiness.cpp │ ├── MonthlyBusiness.cpp │ └── README.md ├── 14-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── buses2.cpp │ ├── buses2.cpp │ └── README.md ├── 15-Practice-Programming-Assignment │ ├── unique.cpp │ └── README.md ├── 04-Practice-Programming-Assignment │ ├── UpdateIfGreater.cpp │ └── README.md ├── 02-Practice-Programming-Assignment │ ├── IsPalindrom.cpp │ └── README.md ├── 16-Practice-Programming-Assignment │ ├── map_values.cpp │ └── README.md ├── 07-Practice-Programming-Assignment │ ├── Reversed.cpp │ └── README.md ├── 08-Practice-Programming-Assignment │ ├── temperature.cpp │ └── README.md ├── 11-Practice-Programming-Assignment │ ├── anagrams.cpp │ └── README.md ├── 13-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── buses1.cpp │ └── README.md └── 12-Practice-Programming-Assignment │ ├── countries.cpp │ └── README.md ├── week-03 ├── W3P1.pdf ├── W3P2.pdf ├── W3P3.pdf ├── README.md ├── 01-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── compare.cpp │ └── README.md ├── 08-Practice-Programming-Assignment │ ├── incognizable.cpp │ └── README.md ├── 02-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── lexicographical_compare.cpp │ └── README.md ├── 07-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── README.md │ └── names3.cpp ├── 04-Programming-Assignment │ ├── Solution │ │ ├── README.md │ │ └── main.cpp │ ├── names1.cpp │ └── README.md ├── 06-Practice-Programming-Assignment │ ├── README.md │ └── reversible_string.cpp ├── 03-Practice-Programming-Assignment │ ├── sorted_strings.cpp │ └── README.md └── 05-Programming-Assignment │ ├── Solution │ ├── README.md │ └── main.cpp │ └── README.md ├── img └── 16-Yandex-291-1500_430-1500_430.jpg └── README.md /week-05/README.md: -------------------------------------------------------------------------------- 1 | Задачи обучения 2 | * Базы данных -------------------------------------------------------------------------------- /week-04/01-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Подход к решению полностью аналогичен рассказанному на лекции. -------------------------------------------------------------------------------- /week-01/W1P4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-01/W1P4.pdf -------------------------------------------------------------------------------- /week-02/W2P1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-02/W2P1.pdf -------------------------------------------------------------------------------- /week-02/W2P2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-02/W2P2.pdf -------------------------------------------------------------------------------- /week-03/W3P1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-03/W3P1.pdf -------------------------------------------------------------------------------- /week-03/W3P2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-03/W3P2.pdf -------------------------------------------------------------------------------- /week-03/W3P3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-03/W3P3.pdf -------------------------------------------------------------------------------- /week-04/W4P1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-04/W4P1.pdf -------------------------------------------------------------------------------- /week-04/W4P2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-04/W4P2.pdf -------------------------------------------------------------------------------- /week-04/W4P3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-04/W4P3.pdf -------------------------------------------------------------------------------- /week-04/W4P4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-04/W4P4.pdf -------------------------------------------------------------------------------- /week-04/main.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-04/main.pdf -------------------------------------------------------------------------------- /week-04/README.md: -------------------------------------------------------------------------------- 1 | Задачи обучения 2 | 3 | * Структуры Date 4 | * Класс Function 5 | * Текстовые файлы и потоки 6 | * Исключения -------------------------------------------------------------------------------- /week-01/03-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Достаточно было решить квадратное уравнение, аккуратно рассмотрев все случаи. -------------------------------------------------------------------------------- /week-02/05-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Поскольку функция *MoveStrings* должна изменить оба переданных вектора, их нужно принять по ссылке. -------------------------------------------------------------------------------- /week-02/README.md: -------------------------------------------------------------------------------- 1 | Задачи обучения 2 | 3 | * Применять функции в С++ 4 | * Применять контейнер vector 5 | * Применять контейнер map 6 | * Применять контейнер set -------------------------------------------------------------------------------- /week-04/03-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Для поддержки умножения и деления достаточно лишь обновить методы *Apply* и *Invert* класса *FunctionPart*. -------------------------------------------------------------------------------- /img/16-Yandex-291-1500_430-1500_430.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/img/16-Yandex-291-1500_430-1500_430.jpg -------------------------------------------------------------------------------- /week-02/06-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | В этой задаче достаточно было перебрать все элементы первой половины вектора и поменять их местами с симметричными им. -------------------------------------------------------------------------------- /week-02/09-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Основная идея решения — сохранить данные о том, беспокоится ли каждый из людей в очереди, в векторе булевских значений. -------------------------------------------------------------------------------- /week-04/10-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | По условию достаточно добавить проверку параметров лишь в параметризованный конструктор класса *Rational* и в оператор деления. -------------------------------------------------------------------------------- /week-02/01-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | *Один из способов написать лаконичный код по этой задаче — заметить, что для положительных x Factorial(x) = x * Factorial(x - 1)*. 2 | -------------------------------------------------------------------------------- /week-03/README.md: -------------------------------------------------------------------------------- 1 | Задачи обучения 2 | 3 | * Применять алгоритмы 4 | * Знать видимость и инициализацию переменных 5 | * Структуры и классы 6 | * Константность методов 7 | * Конструкторы -------------------------------------------------------------------------------- /week-04/06-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Поскольку размер таблицы заранее известен, удобно считывать её вложенными циклами for, сразу выводя считанные значения в нужном формате. -------------------------------------------------------------------------------- /week-04/10-Programming-Assignment/rational_throw.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avtomato/Basics-of-C-plus-plus-development-white-belt/HEAD/week-04/10-Programming-Assignment/rational_throw.cpp -------------------------------------------------------------------------------- /week-03/01-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Чтобы отсортировать вектор целых чисел по модулю, третьим аргументом в функцию *sort* передадим лямбда-функцию, сравнивающие модули переданных чисел. -------------------------------------------------------------------------------- /week-01/07-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Будем идти по строке слева направо циклом *for* и поддерживать текущий ответ. Если очередной символ равен **f**, текущий ответ нужно аккуратно обновить. 2 | -------------------------------------------------------------------------------- /week-02/18-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Решение этой задачи очень похоже на решение задачи «Автобусные остановки — 2». Разница лишь в том, что набор остановок теперь представляет собой не вектор, а множество строк. -------------------------------------------------------------------------------- /week-02/03-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | 1. *IsPalindrom*, проверяющую, является ли строка палиндромом. 2 | 2. *PalindromFilter*, перебирающую все строки из данного вектора и проверяющую для каждой из них требуемые условия. -------------------------------------------------------------------------------- /week-01/08-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Реализуем [алгоритм Евклида](https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%95%D0%B2%D0%BA%D0%BB%D0%B8%D0%B4%D0%B0) для поиска наибольшего общего делителя. -------------------------------------------------------------------------------- /week-02/01-Programming-Assignment/Solution/Factorial.cpp: -------------------------------------------------------------------------------- 1 | int Factorial(int x) { 2 | if (x <= 1) { 3 | return 1; 4 | } else { 5 | return x * Factorial(x - 1); // вычисляем факториал от x-1 и умножаем на x 6 | } 7 | } -------------------------------------------------------------------------------- /week-01/README.md: -------------------------------------------------------------------------------- 1 | Задачи обучения 2 | 3 | * Написать первую программу на С++ 4 | * Применить все самые частые конструкции языка своими руками: ввод и вывод в стандартные потоки, условные операторы, циклы 5 | * Узнать основные типы данных языка С++ -------------------------------------------------------------------------------- /week-02/05-Programming-Assignment/Solution/MoveStrings.cpp: -------------------------------------------------------------------------------- 1 | void MoveStrings(vector& source, vector& destination) { 2 | for (auto w : source) { 3 | destination.push_back(w); 4 | } 5 | source.clear(); 6 | } 7 | -------------------------------------------------------------------------------- /week-02/17-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Чтобы быстро проверять, является ли одно слово синонимом другого, можно было использовать словарь множеств — *map>*: для каждого слова будем хранить множество его синонимов. -------------------------------------------------------------------------------- /week-04/04-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | **Часть 1** 2 | 3 | Будем считывать из файлового потока по одной строке и сразу выводить их в стандартный поток вывода. 4 | 5 | **Часть 2** 6 | 7 | В отличие от предыдущего решения, вывод будет осуществляться в файловый поток. -------------------------------------------------------------------------------- /week-02/10-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Главным в этой задаче было не переусердствовать со вложенными друг в друга структурами. Достаточно хранить лишь дела на текущий месяц в виде вектора векторов строк (двумерного вектора строк): для каждого дня месяца список названий дел. -------------------------------------------------------------------------------- /week-01/01-Programming-Assignment/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | int main() { 7 | int a; 8 | int b; 9 | int sum; 10 | cin >> a >> b; 11 | 12 | sum = a + b; 13 | cout << sum; 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /week-01/02-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Идея решения заключается в следующем: 2 | 3 | * если первая строка меньше (если точнее, не больше) остальных, то она и является минимальной; 4 | * то же самое проверим для второй; 5 | * если ни первая, ни вторая строка не оказались меньше других, минимальной является третья. -------------------------------------------------------------------------------- /week-02/14-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Эта задача призвана продемонстрировать, что одни контейнеры могут содержаться в других даже в качестве ключей. В данном случае стоило использовать *map, int>* — словарь, для каждого набора остановок (вектора строк) хранящий номер соответствующего маршрута. -------------------------------------------------------------------------------- /week-01/08-Programming-Assignment/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | int main() { 7 | int a, b, c; 8 | cin >> a >> b; 9 | 10 | while (b != 0) { 11 | c = a % b; 12 | a = b; 13 | b = c; 14 | } 15 | cout << a; 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /week-01/04-Practice-Programming-Assignment/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | int main() { 7 | int a, b, c; 8 | cin >> a >> b; 9 | 10 | if (b != 0) { 11 | c = a / b; 12 | cout << c; 13 | } else { 14 | cout << "Impossible"; 15 | } 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /week-04/04-Programming-Assignment/Solution/input.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | ifstream input("input.txt"); 9 | 10 | string line; 11 | while (getline(input, line)) { 12 | cout << line << endl; 13 | } 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /week-03/08-Practice-Programming-Assignment/incognizable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | struct Incognizable { 7 | int first = 0; 8 | int second = 0; 9 | }; 10 | 11 | int main() { 12 | Incognizable a; 13 | Incognizable b = {}; 14 | Incognizable c = {0}; 15 | Incognizable d = {0, 1}; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /week-01/06-Practice-Programming-Assignment/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | int main() { 7 | int A, B; 8 | cin >> A >> B; 9 | 10 | while (A <= B) { 11 | if (A % 2 == 0) { 12 | cout << A << " "; 13 | A++; 14 | } 15 | A++; 16 | } 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /week-04/04-Programming-Assignment/input.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | int main() { 9 | ifstream input("input.txt"); 10 | 11 | string line; 12 | if (input.is_open()) { 13 | while (getline(input, line)) 14 | cout << line << endl; 15 | } 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /week-04/04-Programming-Assignment/Solution/output.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | ifstream input("input.txt"); 9 | ofstream output("output.txt"); 10 | 11 | string line; 12 | while (getline(input, line)) { 13 | output << line << endl; 14 | } 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [Основы разработки на C++: белый пояс](https://www.coursera.org/learn/c-plus-plus-white/) by Moscow Institute of Physics and Technology & Yandex 2 | 3 |

4 | 5 | 6 | 7 |

8 | -------------------------------------------------------------------------------- /week-01/02-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() { 7 | string a, b, c; 8 | cin >> a >> b >> c; 9 | 10 | if (a <= b && a <= c) { 11 | cout << a; 12 | } else if (b <= a && b <= c) { 13 | cout << b; 14 | } else { 15 | cout << c; 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /week-01/09-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | 1. Заведём вектор целых чисел, в который будем складывать отдельные биты входного числа. 2 | 2. Считаем входное число и, пока оно больше нуля, будем будем добавлять его младший бит в конец вектора и уменьшать вдвое. 3 | 3. В результате у нас в векторе будут содержатся все биты входного числа от младшего к старшему. 4 | 4. Выведем элементы вектора в обратном порядке. -------------------------------------------------------------------------------- /week-02/01-Programming-Assignment/Factorial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | int Factorial(int x){ 7 | if (x < 1) { 8 | return 1; 9 | } else { 10 | x = x * (Factorial((x - 1))); 11 | return x; 12 | } 13 | } 14 | 15 | int main() { 16 | int y; 17 | cin >> y; 18 | 19 | cout << Factorial(y); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /week-02/15-Practice-Programming-Assignment/unique.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | int main() { 8 | int q; 9 | cin >> q; 10 | set numbers; 11 | 12 | for (int i = 0; i < q; ++i) { 13 | string n; 14 | cin >> n; 15 | numbers.insert(n); 16 | } 17 | cout << numbers.size(); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /week-04/04-Programming-Assignment/output.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | int main() { 9 | ifstream input("input.txt"); 10 | ofstream output("output.txt"); 11 | 12 | string line; 13 | if (input.is_open()) { 14 | while (getline(input, line)) 15 | output << line << "\n"; 16 | } 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /week-01/02-Programming-Assignment/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | int main() { 10 | string a; 11 | string b; 12 | string c; 13 | cin >> a >> b >> c; 14 | 15 | vector words = {a, b, c}; 16 | sort(begin(words), end(words)); 17 | cout << words[0]; 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /week-01/09-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() { 7 | int n; 8 | vector bits; 9 | 10 | cin >> n; 11 | while (n > 0) { 12 | bits.push_back(n % 2); 13 | n /= 2; 14 | } 15 | 16 | for (int i = bits.size() - 1; i >= 0; --i) { 17 | cout << bits[i]; 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /week-02/04-Practice-Programming-Assignment/UpdateIfGreater.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | void UpdateIfGreater(const int& first, int& second) { 7 | int tmp = first; 8 | if (first > second) { 9 | second = tmp; 10 | } 11 | } 12 | 13 | int main() { 14 | int a = 4; 15 | int b = 2; 16 | UpdateIfGreater(a, b); 17 | // b должно стать равно 4 18 | cout << b; 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /week-02/06-Programming-Assignment/Solution/Reverse.cpp: -------------------------------------------------------------------------------- 1 | void Reverse(vector& v) { 2 | int n = v.size(); // для удобства сохраним размер вектора в переменную n 3 | for (int i = 0; i < n / 2; ++i) { 4 | // элемент с индексом i симметричен элементу с индексом n - 1 - i 5 | // поменяем их местами с помощью временной переменной tmp 6 | int tmp = v[i]; 7 | v[i] = v[n - 1 - i]; 8 | v[n - 1 - i] = tmp; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /week-01/09-Programming-Assignment/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | int main() { 9 | int n, x; 10 | cin >> n; 11 | 12 | vector v; 13 | while (n > 0) { 14 | x = n % 2; 15 | v.push_back(x); 16 | n /= 2; 17 | } 18 | reverse(begin(v), end(v)); 19 | for (auto i : v) { 20 | cout << i; 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /week-01/05-Practice-Programming-Assignment/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | int main() { 7 | double N, A, B, X, Y, p; 8 | cin >> N >> A >> B >> X >> Y; 9 | 10 | if (N < A && N < B) { 11 | p = N; 12 | cout << p; 13 | } else if (N >= A && N < B) { 14 | p = N - N * X / 100; 15 | cout << p; 16 | } else { 17 | p = N - N * Y / 100; 18 | cout << p; 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /week-02/02-Practice-Programming-Assignment/IsPalindrom.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | bool IsPalindrom(string s) { 8 | string r = ""; 9 | for (int i = s.size() - 1; i >= 0; --i) { 10 | r += s[i]; 11 | } 12 | if (s == r) { 13 | return true; 14 | } else { 15 | return false; 16 | } 17 | } 18 | 19 | 20 | int main() { 21 | string s2; 22 | cin >> s2; 23 | 24 | cout << IsPalindrom(s2); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /week-04/09-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Функция EnsureEqual #### 2 | 3 | Напишите функцию 4 | ```objectivec 5 | void EnsureEqual(const string& left, const string& right); 6 | ``` 7 | 8 | В случае, если строка **left** не равна строке **right**, функция должна выбрасывать исключение runtime_error с содержанием " != ", где и - строки, которые хранятся в переменных **left** и **right** соответственно. 9 | 10 | Если **left == right**, функция должна корректно завершаться. -------------------------------------------------------------------------------- /week-03/02-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Наиболее нетривиальная часть решения этой задачи — реализовать функцию, сравнивающую две строки без учёта регистра. 2 | 3 | Это можно сделать, например, с помощью функции [lexicographical_compare](http://ru.cppreference.com/w/cpp/algorithm/lexicographical_compare), сравнивающей два диапазона элементов (в нашем случае — два набора символов) с помощью данного компаратора. В компараторе для функции *lexicographical_compare* мы используем функцию *tolower*, возвращающую символ, приведённый к нижнему регистру. -------------------------------------------------------------------------------- /week-03/07-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Новые уточнения в целом упрощают задачу по сравнению с предыдущей версией: функция *BuildFullName* больше не нужна, потому что имя и фамилия всегда известны — для получения полного имени достаточно объединить их через пробел. 2 | 3 | В связи с добавлением требований про год рождения потребуются следующие изменения: 4 | 5 | 1. Напишем конструктор, сохраняющий в поле класса год рождения, а имя и фамилию — в соответствующие словари. 6 | 2. Во всех методах будем сравнивать переданный год с годом рождения. -------------------------------------------------------------------------------- /week-04/05-Practice-Programming-Assignment/accuracy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | int main() { 10 | ifstream input("input.txt"); 11 | 12 | double num; 13 | cout << setprecision(3) << fixed; 14 | if (input.is_open()) { 15 | while (input) { 16 | input >> num; 17 | if (input) { 18 | cout << num << endl; 19 | } 20 | } 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /week-01/08-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Наибольший общий делитель #### 2 | 3 | В *stdin* даны два натуральных числа. Найти их наибольший общий делитель. 4 | 5 | 6 | | stdin | stdout | 7 | |:------------------------------:|:------------------------------:| 8 | | 25 27 | 1 | 9 | | 12 16 | 4 | 10 | | 13 13 | 13 | 11 | -------------------------------------------------------------------------------- /week-01/07-Programming-Assignment/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | int main() { 8 | int n = 0; 9 | int i = 0; 10 | string s; 11 | cin >> s; 12 | 13 | while (i < s.size()) { 14 | if (s[i] == 'f') { 15 | n += 1; 16 | } 17 | if (n == 2) { 18 | cout << i; 19 | break; 20 | } 21 | i += 1; 22 | } 23 | if (n == 1) { 24 | cout << "-1"; 25 | } else if (n == 0) { 26 | cout << "-2"; 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /week-02/06-Programming-Assignment/Reverse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | void Reverse(vector& v) { 9 | vector tmp; 10 | for (int i = v.size() - 1; i >= 0; --i) { 11 | tmp.push_back(v[i]); 12 | } 13 | v.clear(); 14 | v = tmp; 15 | } 16 | 17 | int main() { 18 | vector numbers = {1, 5, 3, 4, 2}; 19 | Reverse(numbers); 20 | // numbers должен оказаться равен {2, 4, 3, 5, 1} 21 | for (auto n : numbers) { 22 | cout << n << " "; 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /week-03/01-Programming-Assignment/compare.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | void PrintVector(const vector& v) { 9 | for (const auto i : v) { 10 | cout << i << " "; 11 | } 12 | } 13 | 14 | bool Compare(int i, int j) { 15 | return abs(i) < abs(j); 16 | } 17 | 18 | int main() { 19 | int n; 20 | cin >> n; 21 | vector v(n); 22 | 23 | for (int& s : v) { 24 | cin >> s; 25 | } 26 | 27 | sort(begin(v), end(v), Compare); 28 | PrintVector(v); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /week-04/12-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class TimeServer { 7 | public: 8 | string GetCurrentTime() { 9 | // поместим вызов функции AskTimeServer в try-catch блок 10 | try { 11 | last_fetched_time = AskTimeServer(); 12 | } catch (const system_error&) { // ловим только system_error 13 | } 14 | // возвращаем значение поля — либо обновлённое, либо нет 15 | return last_fetched_time; 16 | } 17 | 18 | private: 19 | string last_fetched_time = "00:00:00"; 20 | }; 21 | -------------------------------------------------------------------------------- /week-03/08-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Способы инициализации #### 2 | 3 | Определите тип *Incognizable*, для которого следующий код будет корректен: 4 | ```objectivec 5 | int main() { 6 | Incognizable a; 7 | Incognizable b = {}; 8 | Incognizable c = {0}; 9 | Incognizable d = {0, 1}; 10 | return 0; 11 | } 12 | ``` 13 | 14 | ##### Пояснение ##### 15 | В этой задаче вам надо прислать на проверку файл с реализацией структуры или класса *Incognizable*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 16 | -------------------------------------------------------------------------------- /week-05/01-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Ключевой момент в решении задачи — выбор контейнера для хранения событий. Поскольку нам требуется быстрый поиск событий по дате, а также быстрое удаление конкретного события, используем словарь множеств — *map>*, для каждой даты хранящий множество соответствующих событий. 2 | 3 | Кроме того, важно было аккуратно организовать обработку ошибок — тут очень помогает механизм исключений. Обратите внимание, например, на проверку корректности дня и месяца в дате: она вынесена в конструктор даты, что позволяет не заботиться об этом во всех остальных функциях, работающих с датами. -------------------------------------------------------------------------------- /week-02/06-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Разворот последовательности #### 2 | 3 | Реализуйте функцию *void Reverse(vector& v)*, которая переставляет элементы вектора в обратном порядке. 4 | 5 | ##### Пример ##### 6 | 7 | ```objectivec 8 | vector numbers = {1, 5, 3, 4, 2}; 9 | Reverse(numbers); 10 | // numbers должен оказаться равен {2, 4, 3, 5, 1} 11 | ``` 12 | 13 | ##### Пояснение ##### 14 | В этой задаче на проверку вам надо прислать файл с реализацией функции *Reverse*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 15 | -------------------------------------------------------------------------------- /week-02/16-Practice-Programming-Assignment/map_values.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | setBuildMapValuesSet(const map& m) { 10 | set s; 11 | for (const auto& item : m) { 12 | s.insert(item.second); 13 | } 14 | return s; 15 | } 16 | 17 | int main() { 18 | set values = BuildMapValuesSet({{1, "odd"}, {2, "even"}, {3, "odd"}, {4, "even"}, {5, "odd"}}); 19 | 20 | for (const string& value : values) { 21 | cout << value << endl; 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /week-04/09-Practice-Programming-Assignment/ensure_equal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | void EnsureEqual(const string& left, const string& right) { 7 | if (left != right) { 8 | throw runtime_error(left + " != " + right); 9 | } else { 10 | cout << left << " " << right << endl; 11 | } 12 | }; 13 | 14 | int main() { 15 | string first = "1"; 16 | string second = "2"; 17 | 18 | try { 19 | EnsureEqual(first, second); 20 | } catch (const exception& ex) { 21 | cout << "exception: " << ex.what() << endl; 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /week-02/07-Practice-Programming-Assignment/Reversed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | vector Reversed(const vector& v) { 9 | vector tmp; 10 | for (int i = v.size() - 1; i >= 0; --i) { 11 | tmp.push_back(v[i]); 12 | } 13 | return tmp; 14 | } 15 | 16 | int main() { 17 | vector numbers = {1, 5, 3, 4, 2}; 18 | vector num; 19 | num = Reversed(numbers); 20 | // num должен оказаться равен {2, 4, 3, 5, 1} 21 | for (auto n : num) { 22 | cout << n << " "; 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /week-01/01-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: A + B #### 2 | 3 | На вход программе через стандартный ввод передаются два целых числа, по модулю не превышающие 100000. Выведите в стандартный вывод их сумму. 4 | 5 | | stdin | stdout | 6 | |:------------:|:------------:| 7 | | 2 3 | 5 | 8 | | -4 -9 | - 13 | 9 | | -1 2 | 1 | 10 | 11 | ##### Пояснение ##### 12 | Если вы не знаете, как компилировать и запускать программы на C++, вы можете просмотреть видео из блока "Компиляция, запуск, отладка" и, настроив среду разработки, вернуться к этой задаче. 13 | -------------------------------------------------------------------------------- /week-01/02-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Минимальная строка #### 2 | 3 | В стандартном потоке даны три строки, разделённые пробелом. Каждая строка состоит из строчных латинских букв и имеет длину не более 30 символов. Выведите в стандартный вывод лексикографически минимальную из них. 4 | 5 | | stdin | stdout | 6 | |:------------------------------:|:------------------------------:| 7 | | milk milkshake month | milk | 8 | | c a b | a | 9 | | fire fog wood | fire | -------------------------------------------------------------------------------- /week-01/04-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Деление #### 2 | 3 | Дано два натуральных числа A и B, не превышающих 1 000 000. Напишите программу, которая вычисляет целую часть частного от деления A на B. 4 | 5 | Если B = 0, выведите "Impossible". 6 | 7 | | stdin | stdout | 8 | |:------------------------------:|:------------------------------:| 9 | | 10 2 | 5 | 10 | | 3 5 | 0 | 11 | | 11 0 | Impossible | 12 | -------------------------------------------------------------------------------- /week-01/03-Programming-Assignment/equation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | int main() { 8 | double a, b, c; 9 | cin >> a >> b >> c; 10 | 11 | if (a == 0) { 12 | if (b != 0) { 13 | cout << -1.0 * c / b; 14 | } 15 | } else { 16 | double discriminant = b * b - 4 * a * c; 17 | if (discriminant > 0) { 18 | cout << (-b + sqrt(discriminant)) / (2 * a) << " " << (-b - sqrt(discriminant)) / (2 * a); 19 | } else if (discriminant == 0) { 20 | cout << -1.0 * b / (2 * a); 21 | } 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /week-03/04-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | В приватных полях класса *Person* сохраним два словаря: 2 | 3 | 1. first_names, для каждого года с изменением имени хранящий соответствующее имя. 4 | 2. last_names, для каждого года с изменением фамилии хранящий соответствующую фамилию. 5 | Методы *ChangeFirstName* и *ChangeLastName* будут лишь добавлять очередную запись в соответствующий словарь. 6 | 7 | В методе *GetFulName* найдём имя и фамилию, соответствующие данному году, и затем аккуратно их выведем, соблюдая все требования условия. Здесь нам пригодится функция *FindNameByYear*, принимающая на вход год и словарь «год → имя/фамилия» и возвращающая имя/фамилию, соответствующую данному году. -------------------------------------------------------------------------------- /week-01/07-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Второе вхождение #### 2 | 3 | Дана строка. Найдите в этой строке второе вхождение буквы **f** и выведите индекс этого вхождения. Если буква **f** в данной строке встречается только один раз, выведите число -1, а если не встречается ни разу, выведите число -2. Индексы нумеруются с нуля. 4 | 5 | 6 | | stdin | stdout | 7 | |:------------------------------:|:------------------------------:| 8 | | comfort | -1 | 9 | | coffee | 3 | 10 | | car | -2 | 11 | -------------------------------------------------------------------------------- /week-02/08-Practice-Programming-Assignment/temperature.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | int main() { 9 | int n, sum = 0, average; 10 | cin >> n; 11 | vector v(n); 12 | 13 | for (int & s : v) { 14 | cin >> s; 15 | sum += s; 16 | } 17 | 18 | average = sum / n; 19 | 20 | vector temperature; 21 | for (int i = 0; i < v.size(); i++) { 22 | if (v[i] > average) { 23 | temperature.push_back(i); 24 | } 25 | } 26 | cout << temperature.size() << endl; 27 | for (const auto& num : temperature) { 28 | cout << num << " "; 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /week-02/15-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Количество уникальных строк #### 2 | 3 | Дан набор строк. Найдите количество уникальных строк в этом наборе. 4 | 5 | ##### Формат ввода ##### 6 | Сначала вводится количество строк *N*, затем — сами *N* строк, разделённые пробелом. Все строки состоят лишь из латинских букв, цифр и символов подчёркивания. 7 | 8 | ##### Формат вывода ##### 9 | Выведите единственное целое число — количество уникальных строк в данном наборе. 10 | 11 | ##### Пример ##### 12 | ###### Ввод ###### 13 | ```objectivec 14 | 6 15 | first 16 | second 17 | first 18 | third 19 | second 20 | second 21 | ``` 22 | 23 | ###### Вывод ###### 24 | ```objectivec 25 | 3 26 | ``` 27 | -------------------------------------------------------------------------------- /week-03/01-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | int main() { 10 | 11 | // считываем вектор 12 | int n; 13 | cin >> n; 14 | vector v(n); 15 | for (int& x : v) { 16 | cin >> x; 17 | } 18 | 19 | // сортируем 20 | sort(begin(v), end(v), 21 | // функция, сравнивающая abs(l) и abs(r) — модули чисел l и r 22 | [](int l, int r) { 23 | return abs(l) < abs(r); 24 | } 25 | ); 26 | 27 | // выводим отсорированный вектор 28 | for (int x : v) { 29 | cout << x << " "; 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /week-02/07-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Разворот последовательности — 2 #### 2 | 3 | Реализуйте функцию *vector Reversed(const vector& v)*, возвращающую копию вектора v, в которой числа переставлены в обратном порядке. 4 | 5 | ##### Пример ##### 6 | 7 | | Вектор v | Результат функции | 8 | |:------------------------------:|:------------------------------:| 9 | | 1, 5, 3, 4, 2 | 2, 4, 3, 5, 1 | 10 | 11 | ##### Пояснение ##### 12 | В этой задаче на проверку вам надо прислать файл с реализацией функции *Reversed*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 13 | -------------------------------------------------------------------------------- /week-02/04-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Максимизатор #### 2 | 3 | Напишите функцию *UpdateIfGreater*, которая принимает два целочисленных аргумента: *first* и *second*. Если *first* оказался больше *second*, Ваша функция должна записывать в *second* значение параметра *first*. При этом изменение параметра *second* должно быть видно на вызывающей стороне. 4 | 5 | ##### Пример ##### 6 | 7 | ```objectivec 8 | int a = 4; 9 | int b = 2; 10 | UpdateIfGreater(a, b); 11 | // b должно стать равно 4 12 | ``` 13 | 14 | ##### Пояснение ##### 15 | В этой задаче на проверку вам надо прислать файл с реализацией функции *UpdateIfGreater*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 16 | -------------------------------------------------------------------------------- /week-02/11-Practice-Programming-Assignment/anagrams.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | map BuildCharCounters(string& s) { 9 | map counters; 10 | for (const char& c : s) { 11 | ++counters[c]; 12 | } 13 | return counters; 14 | } 15 | 16 | int main() { 17 | int q; 18 | cin >> q; 19 | 20 | for (int i = 0; i < q; ++i) { 21 | string s1, s2; 22 | cin >> s1 >> s2; 23 | 24 | map t = BuildCharCounters(s1); 25 | map t2 = BuildCharCounters(s2); 26 | if (t == t2) { 27 | cout << "YES" << endl; 28 | } else { 29 | cout << "NO" << endl; 30 | } 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /week-02/05-Programming-Assignment/MoveStrings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | void MoveStrings(vector& source , vector& destination) { 9 | for (auto w : source) { 10 | destination.push_back(w); 11 | } 12 | source.clear(); 13 | } 14 | 15 | int main() { 16 | vector source = {"a", "b", "c"}; 17 | vector destination = {"z"}; 18 | MoveStrings(source, destination); 19 | // source должен оказаться пустым 20 | // destination должен содержать строки "z", "a", "b", "c" именно в таком порядке 21 | cout << source.size() << endl; 22 | cout << destination.size() << endl; 23 | for (auto c : destination) { 24 | cout << c; 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /week-02/03-Programming-Assignment/PalindromFilter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | vector PalindromFilter(vector words, int minLength){ 9 | vector palindrom; 10 | for (auto w : words) { 11 | string r = ""; 12 | for (int i = w.size() - 1; i >= 0; --i) { 13 | r += w[i]; 14 | } 15 | if (w == r and w.size() >= minLength){ 16 | palindrom.push_back(w); 17 | } 18 | } 19 | return palindrom; 20 | } 21 | 22 | int main() { 23 | vector v; 24 | int n; 25 | cin >> n; 26 | vector total; 27 | 28 | total = PalindromFilter(v, n); 29 | for (auto t : total) { 30 | cout << t << " "; 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /week-04/05-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Вывод с точностью #### 2 | 3 | В файле *input.txt* записаны вещественные числа, по одному на строчку. На стандартный вывод напечатайте эти числа в том же порядке, по одному на строке, но сделайте так, чтобы у каждого из них было ровно три знака после десятичной точки (округление производится по стандартным правилам, т.е. 0.1234 округляется до 0.123, а 0.1235 до 0.124). 4 | 5 | ##### Пример ввода 1 ##### 6 | ```objectivec 7 | 5 8 | 0.34567 9 | 10.4 10 | ``` 11 | ##### Пример вывода 1 ##### 12 | ```objectivec 13 | 5.000 14 | 0.346 15 | 10.400 16 | ``` 17 | ##### Пример ввода 2 ##### 18 | ```objectivec 19 | 3.33353 20 | 3.333 21 | 3.3 22 | ``` 23 | ##### Пример вывода 2 ##### 24 | ```objectivec 25 | 3.334 26 | 3.333 27 | 3.300 28 | ``` 29 | -------------------------------------------------------------------------------- /week-01/09-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Деление #### 2 | 3 | На вход дано натуральное число _N_. Выведите его в двоичной системе счисления без ведущих нулей. 4 | 5 | ##### Пример ##### 6 | 7 | | stdin | stdout | 8 | |:------------------------------:|:------------------------------:| 9 | | 5 | 101 | 10 | | 32 | 100000 | 11 | | 1 | 1 | 12 | 13 | ##### Подсказка ##### 14 | 15 | число _N_ можно считывать в переменную типа int 16 | в этой задаче вам может пригодиться контейнер *vector*; напоминаем, что добавление значения **x** в конец вектора **v** делается так: **v.push_back(x)**; 17 | -------------------------------------------------------------------------------- /week-03/02-Programming-Assignment/lexicographical_compare.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | void PrintVector(const vector& v) { 10 | for (const auto i : v) { 11 | cout << i << " "; 12 | } 13 | } 14 | 15 | string Transform(string& s) { 16 | string temp = ""; 17 | for (int i = 0; i < s.size(); ++i) { 18 | temp += tolower(s[i]); 19 | } 20 | return temp; 21 | } 22 | 23 | bool Compare(string i, string j) { 24 | return Transform(i) < Transform(j); 25 | } 26 | 27 | int main() { 28 | int n; 29 | cin >> n; 30 | vector v(n); 31 | 32 | for (string& w : v) { 33 | cin >> w; 34 | } 35 | 36 | sort(begin(v), end(v), Compare); 37 | PrintVector(v); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /week-01/08-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() { 7 | int a, b; 8 | cin >> a >> b; 9 | 10 | // пока оба числа положительны, будем их уменьшать, не меняя их НОД 11 | while (a > 0 && b > 0) { 12 | 13 | // возьмём большее из чисел и заменим его остатком от деления на второе 14 | // действительно, если a и b делятся на x, то a - b и b делятся на x 15 | // тогда и a % b и b делятся на x, так что можно a заменить на a % b 16 | if (a > b) { 17 | a %= b; 18 | } else { 19 | b %= a; 20 | } 21 | 22 | } 23 | 24 | // если одно из чисел оказалось равно нулю, значит, на последней итерации 25 | // большее число разделилось на меньшее 26 | cout << a + b; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /week-01/05-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Расчёт стоимости товара #### 2 | 3 | Написать программу вычисления стоимости покупки с учётом скидки. Скидка в X процентов предоставляется, если сумма покупки больше _A_ рублей, в _Y_ процентов - если сумма больше _B_ рублей. 4 | 5 | В стандартном вводе содержится пять вещественных чисел, разделённых пробелом: _N, A, B, X, Y (A < B)_ - где _N_ - исходная стоимость товара. Выведите стоимость покупки с учётом скидки. 6 | 7 | | stdin | stdout | 8 | |:------------------------------:|:------------------------------:| 9 | | 100 110 120 5 10 | 100 | 10 | | 115 110 120 5 10 | 109.25 | 11 | | 150 110 120 5 12.5 | 131.25 | 12 | -------------------------------------------------------------------------------- /week-02/18-Programming-Assignment/Solution/buses3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() { 9 | int q; 10 | cin >> q; 11 | 12 | map, int> buses; 13 | 14 | for (int i = 0; i < q; ++i) { 15 | int n; 16 | cin >> n; 17 | set stops; 18 | for (int j = 0; j < n; ++j) { 19 | string stop; 20 | cin >> stop; 21 | stops.insert(stop); 22 | } 23 | if (buses.count(stops) == 0) { 24 | const int new_number = buses.size() + 1; 25 | buses[stops] = new_number; 26 | cout << "New bus " << new_number << endl; 27 | } else { 28 | cout << "Already exists for " << buses[stops] << endl; 29 | } 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /week-02/13-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Пожалуй, самое сложное в этой задаче — внимательно прочитать условие и аккуратно реализовать все его требования, выбрав при этом правильные контейнеры. 2 | 3 | Поскольку необходимо было получать как список остановок для конкретного автобуса, так и список автобусов для конкретной остановки, логичнее всего было определить два словаря — *buses_to_stops* и *stops_to_buses* со строковыми ключами и значениями типа *vector< string >*. 4 | 5 | Ответы на большинство запросов вынесем в отдельные функции: это позволит повысить читаемость кода. Заметьте, что при этом не всегда удаётся передавать словари по константным ссылкам: это происходит из-за того, что использование квадратных скобок (например, в коде *stops_to_buses[stop]*) теоретически может изменить словарь. В этой ситуации стоило бы использовать метод at вместо квадратных скобок — мы рассмотрим его в следующем курсе. -------------------------------------------------------------------------------- /week-02/08-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Средняя температура #### 2 | 3 | Даны значения температуры, наблюдавшиеся в течение _N_ подряд идущих дней. Найдите номера дней (в нумерации с нуля) со значением температуры выше среднего арифметического за все _N_ дней. 4 | 5 | Гарантируется, что среднее арифметическое значений температуры является целым числом. 6 | 7 | ##### Формат ввода ##### 8 | Вводится число _N_, затем _N_ неотрицательных целых чисел — значения температуры в 0-й, 1-й, ... _(N−1)_-й день. 9 | 10 | ##### Формат вывода ##### 11 | Первое число _K_ — количество дней, значение температуры в которых выше среднего арифметического. Затем _K_ целых чисел — номера этих дней. 12 | 13 | ##### Пример ##### 14 | ###### Ввод ###### 15 | ```objectivec 16 | 5 17 | 7 6 3 0 9 18 | ``` 19 | ###### Вывод ###### 20 | ```objectivec 21 | 3 22 | 0 1 4 23 | ``` 24 | -------------------------------------------------------------------------------- /week-02/02-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Палиндром #### 2 | 3 | Напишите функцию, которая 4 | 5 | * называется *IsPalindrom* 6 | * возвращает *bool* 7 | * принимает параметр типа string и возвращает, является ли переданная строка палиндромом 8 | 9 | Палиндром - это слово или фраза, которые одинаково читаются слева направо и справа налево. 10 | 11 | | Аргумент функции | Результат | 12 | |:------------------------------:|:------------------------------:| 13 | | madam | true | 14 | | gentleman | false | 15 | 16 | ##### Пояснение ##### 17 | В этой задаче на проверку вам надо прислать файл с реализацией функции *IsPalindrom*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 18 | -------------------------------------------------------------------------------- /week-01/06-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Чётные числа #### 2 | 3 | Дано два целых числа *A* и *B* *(A <= B, A >= 1, B <= 30000)*. Выведите через пробел все чётные числа от *A* до *B* (включительно). 4 | 5 | *Для проверки целого числа x на чётность используется операция взятия остатка от деления на 2, которая в C++ оформляется с помощью символа "%". Например,* 6 | 7 | ```objectivec 8 | int x; 9 | cin >> x; 10 | if (x % 2 == 0) { 11 | // x - чётное число 12 | } else { 13 | // x - нечётное число 14 | } 15 | ``` 16 | 17 | | stdin | stdout | 18 | |:------------------------------:|:------------------------------:| 19 | | 1 10 | 2 4 6 8 10 | 20 | | 2 3 | 2 | 21 | | 9 11 | 10 | 22 | -------------------------------------------------------------------------------- /week-02/09-Programming-Assignment/queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | int main() { 10 | int Q; 11 | cin >> Q; 12 | vector v; 13 | 14 | int n = 0; 15 | while (n < Q){ 16 | string s; 17 | cin >> s; 18 | if (s == "COME") { 19 | int k; 20 | cin >> k; 21 | int c = v.size() + k; 22 | v.resize(c, 0); 23 | } else if(s == "WORRY") { 24 | int i; 25 | cin >> i; 26 | v[i] = 1; 27 | } else if(s == "QUIET") { 28 | int i; 29 | cin >> i; 30 | v[i] = 0; 31 | } else if(s == "WORRY_COUNT") { 32 | int quanity = count(begin(v), end(v), 1); 33 | cout << quanity << endl; 34 | } 35 | n += 1; 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /week-02/01-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Факториал #### 2 | 3 | Напишите функцию, которая 4 | 5 | * называется *Factorial* 6 | * возвращает *int* 7 | * принимает *int* и возвращает факториал своего аргумента. Гарантируется, что аргумент функции по модулю не превышает 10. Для отрицательных аргументов функция должна возвращать 1. 8 | 9 | | Аргумент функции | Результат | 10 | |:------------------------------:|:------------------------------:| 11 | | 1 | 1 | 12 | | -2 | 1 | 13 | | 4 | 24 | 14 | 15 | ##### Пояснение ##### 16 | В этой задаче на проверку вам надо прислать файл с реализацией функции *Factorial*. **Этот файл не должен содержать функцию main**. Если в нём будет функция main, вы получите ошибку компиляции. 17 | -------------------------------------------------------------------------------- /week-04/06-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Чтение и вывод таблицы #### 2 | 3 | В первой строке файла *input.txt* записаны два числа *N* и *M*. Далее в файле находится таблица из *N* строк и *M* столбцов, представленная в формате *CSV (comma-separated values)*. Такой формат часто используется для текстового представления таблиц с данными: в файле несколько строк, значения из разных ячеек внутри строки отделены друг от друга запятыми. Ваша задача — вывести данные на экран в виде таблицы, размер ячейки которой равен 10, соседние ячейки отделены друг от друга пробелом. После последней ячейки пробела быть не должно. Гарантируется, что в таблице будет ровно *N* строк и *M* столбцов, значение каждой из ячеек — целое число. 4 | 5 | ##### Пример ввода ##### 6 | ```objectivec 7 | 2 3 8 | 1,2,3 9 | 4,5,6 10 | ``` 11 | 12 | ##### Пример вывода ##### 13 | ```objectivec 14 | 1 2 3 15 | 4 5 6 16 | ``` 17 | -------------------------------------------------------------------------------- /week-01/07-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() { 7 | string s; 8 | cin >> s; 9 | 10 | int result = -2; // текущий ответ 11 | // если f ни разу не встретится, он останется равным -2 12 | 13 | for (int i = 0; i < s.size(); ++i) { 14 | // если текущий символ равен f, обновим текущий ответ 15 | if (s[i] == 'f') { 16 | 17 | // есди до этого не было ни одного вхождения, значит, сейчас нашли первое 18 | if (result == -2) { 19 | result = -1; // теперь вхождение ровно одно 20 | 21 | // до этого было ровно одно вхождение → сейчас как раз второе 22 | } else if (result == -1) { 23 | result = i; 24 | break; // цикл можно завершить, потому что ответ уже найден 25 | } 26 | 27 | } 28 | } 29 | 30 | cout << result; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /week-02/16-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Множество значений словаря #### 2 | 3 | Напишите функцию *BuildMapValuesSet*, принимающую на вход словарь *map* и возвращающую множество значений этого словаря: 4 | 5 | ```objectivec 6 | set BuildMapValuesSet(const map& m) { 7 | // ... 8 | } 9 | ``` 10 | 11 | ##### Пример ##### 12 | ###### Код ###### 13 | ```objectivec 14 | set values = BuildMapValuesSet({ 15 | {1, "odd"}, 16 | {2, "even"}, 17 | {3, "odd"}, 18 | {4, "even"}, 19 | {5, "odd"} 20 | }); 21 | 22 | for (const string& value : values) { 23 | cout << value << endl; 24 | } 25 | ``` 26 | 27 | ###### Вывод ###### 28 | ```objectivec 29 | even 30 | odd 31 | ``` 32 | 33 | В этой задаче на проверку вам надо прислать файл с реализацией функции *BuildMapValuesSet*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 34 | -------------------------------------------------------------------------------- /week-04/01-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct Specialization { 7 | explicit Specialization(const string& new_value) { 8 | value = new_value; 9 | } 10 | string value; 11 | }; 12 | 13 | struct Course { 14 | explicit Course(const string& new_value) { 15 | value = new_value; 16 | } 17 | string value; 18 | }; 19 | 20 | struct Week { 21 | explicit Week(const string& new_value) { 22 | value = new_value; 23 | } 24 | string value; 25 | }; 26 | 27 | struct LectureTitle { 28 | LectureTitle(const Specialization& new_specialization, 29 | const Course& new_course, 30 | const Week& new_week) { 31 | specialization = new_specialization.value; 32 | course = new_course.value; 33 | week = new_week.value; 34 | } 35 | string specialization; 36 | string course; 37 | string week; 38 | }; 39 | -------------------------------------------------------------------------------- /week-02/03-Programming-Assignment/Solution/PalindromFilter.cpp: -------------------------------------------------------------------------------- 1 | // определяет, является ли строка s палиндромом 2 | bool IsPalindrom(string s) { 3 | 4 | // переберём все символы s[i] из первой половины строки 5 | for (size_t i = 0; i < s.size() / 2; ++i) { 6 | // s[s.size() - i - 1] — символ, симметричный символу s[i] 7 | if (s[i] != s[s.size() - i - 1]) { 8 | return false; // если они не совпадают, строка точно не палиндром 9 | } 10 | } 11 | 12 | // если все пары символов совпадают, строка — палиндром 13 | return true; 14 | } 15 | 16 | vector PalindromFilter(vector words, int min_length) { 17 | vector result; 18 | // перебираем все элементы вектора words 19 | for (auto s : words) { 20 | // если требуеые условия выполняются, добавляем s к ответу 21 | if (s.size() >= min_length && IsPalindrom(s)) { 22 | result.push_back(s); 23 | } 24 | } 25 | return result; 26 | } 27 | -------------------------------------------------------------------------------- /week-01/03-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Уравнение #### 2 | 3 | На вход вашей программе в стандартном вводе даны действительные коэффициенты _A_, _B_ и C уравнения _Ax² + Bx + C = 0_. Выведите все его различные действительные корни в любом порядке. Гарантируется, что хотя бы один из коэффициентов не равен нулю. 4 | 5 | | stdin | stdout | 6 | |:------------------------------:|:------------------------------:| 7 | | 2 5 2 | -0.5 -2 | 8 | | 2 4 2 | -1 | 9 | | 2 1 2 | | 10 | | 0 4 10 | -2.5 | 11 | 12 | ##### Подсказка ##### 13 | 14 | Для вычисления квадратного корня используйте функцию _sqrt_ из библиотеки _cmath_. Чтобы подключить библиотеку, в начале программы напишите 15 | ```objectivec 16 | #include 17 | ``` 18 | -------------------------------------------------------------------------------- /week-02/14-Programming-Assignment/buses2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | 10 | int main() { 11 | int q; 12 | cin >> q; 13 | map> buses; 14 | int m = 1; 15 | 16 | for (int i = 0; i < q; ++i) { 17 | int n; 18 | cin >> n; 19 | vector v(n); 20 | for (string& s : v) { 21 | cin >> s; 22 | } 23 | int c = 0; 24 | int j; 25 | for (const auto& item : buses) { 26 | if (item.second == v) { 27 | c = 1; 28 | j = item.first; 29 | } 30 | } 31 | if (c == 1) { 32 | cout << "Already exists for " << j << endl; 33 | } else if (c == 0) { 34 | buses[m] = v; 35 | cout << "New bus " << m << endl; 36 | m += 1; 37 | } 38 | } 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/Source/rational_mult_div.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Rational { 5 | // Вставьте сюда реализацию класса Rational из первой части 6 | }; 7 | 8 | // Вставьте сюда реализацию operator == для класса Rational из второй части 9 | 10 | // Реализуйте для класса Rational операторы * и / 11 | 12 | int main() { 13 | { 14 | Rational a(2, 3); 15 | Rational b(4, 3); 16 | Rational c = a * b; 17 | bool equal = c == Rational(8, 9); 18 | if (!equal) { 19 | cout << "2/3 * 4/3 != 8/9" << endl; 20 | return 1; 21 | } 22 | } 23 | 24 | { 25 | Rational a(5, 4); 26 | Rational b(15, 8); 27 | Rational c = a / b; 28 | bool equal = c == Rational(2, 3); 29 | if (!equal) { 30 | cout << "5/4 / 15/8 != 2/3" << endl; 31 | return 2; 32 | } 33 | } 34 | 35 | cout << "OK" << endl; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /week-04/06-Programming-Assignment/table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | int main() { 9 | ifstream input("input.txt"); 10 | 11 | int row = 0; 12 | int column = 0; 13 | if (input.is_open()) { 14 | input >> row; 15 | input.ignore(1); 16 | input >> column; 17 | for (int i=0; i < row; ++i) { 18 | for (int j=0; j <= (column*2-1); ++j) { 19 | int n; 20 | cout << setw(10) << fixed; 21 | if (j % 2 == 0 && j < (column*2-2)) { 22 | input >> n; 23 | cout << n << " "; 24 | } else if (j % 2 == 0 && j == (column*2-2)) { 25 | input >> n; 26 | cout << n; 27 | } else { 28 | input.ignore(1); 29 | } 30 | } 31 | cout << endl; 32 | } 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /week-03/06-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Строка #### 2 | 3 | Реализуйте класс *ReversibleString*, хранящий строку и поддерживающий методы *Reverse* для переворота строки и *ToString* для получения строки. 4 | 5 | ##### Пример ##### 6 | ###### Код ###### 7 | ```objectivec 8 | int main() { 9 | ReversibleString s("live"); 10 | s.Reverse(); 11 | cout << s.ToString() << endl; 12 | 13 | s.Reverse(); 14 | const ReversibleString& s_ref = s; 15 | string tmp = s_ref.ToString(); 16 | cout << tmp << endl; 17 | 18 | ReversibleString empty; 19 | cout << '"' << empty.ToString() << '"' << endl; 20 | 21 | return 0; 22 | } 23 | ``` 24 | 25 | ###### Вывод ###### 26 | ```objectivec 27 | evil 28 | live 29 | "" 30 | ``` 31 | 32 | ##### Пояснение ##### 33 | В этой задаче вам надо прислать на проверку файл с реализацией класса *ReversibleString*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 34 | -------------------------------------------------------------------------------- /week-03/01-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Сортировка целых чисел по модулю #### 2 | 3 | ##### Условие ##### 4 | В стандартном потоке дана одна строка, состоящая из *N + 1* целых чисел. Первым числом идёт само число *N*. Далее следуют ещё *N* чисел, обозначим их за массив *A*. Между собой числа разделены пробелом. 5 | 6 | Отсортируйте массив *А* по модулю и выведите его в стандартный поток. 7 | 8 | ##### Ограничения ##### 9 | 10 | * 0 <= N <= 1000 11 | * -1000000 <= A[i] <= 1000000 12 | 13 | 14 | ##### Пример ##### 15 | | stdin | stdout | 16 | |:------------------------------:|:------------------------------:| 17 | | 2 -4 3 | 3 -4 | 18 | | 3 1 -3 2 | 1 2 -3 | 19 | 20 | 21 | ##### Подсказка ##### 22 | функция sort дополнительно принимает третий аргумент. Изучите его подробнее [по ссылке](http://www.cplusplus.com/reference/algorithm/sort/?kw=sort). 23 | -------------------------------------------------------------------------------- /week-02/18-Programming-Assignment/buses3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | 10 | int main() { 11 | int q; 12 | cin >> q; 13 | map> buses; 14 | int m = 1; 15 | 16 | for (int i = 0; i < q; ++i) { 17 | int n; 18 | cin >> n; 19 | vector v(n); 20 | for (string& s : v) { 21 | cin >> s; 22 | } 23 | set t(begin(v), end(v)); 24 | int c = 0; 25 | int j; 26 | for (const auto& item : buses) { 27 | if (item.second == t) { 28 | c = 1; 29 | j = item.first; 30 | } 31 | } 32 | if (c == 1) { 33 | cout << "Already exists for " << j << endl; 34 | } else if (c == 0) { 35 | buses[m] = t; 36 | cout << "New bus " << m << endl; 37 | m += 1; 38 | } 39 | } 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /week-01/03-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() { 7 | double A, B, C; 8 | cin >> A >> B >> C; 9 | 10 | // найдём дискриминант 11 | double D = B * B - 4 * A * C; 12 | 13 | // если A равно нулю, то уравнение линейное: Bx + C = 0 14 | if (A == 0) { 15 | 16 | // Bx = -C => x = -C / B 17 | if (B != 0) { 18 | cout << -C / B << endl; 19 | } 20 | // если B равно нулю, корней нет 21 | 22 | } else if (D == 0) { // случай с нулевым дискриминантом 23 | 24 | // корень ровно один 25 | cout << -B / (2 * A) << endl; 26 | 27 | } else if (D > 0) { // в случае с положительным дискриминантом корня два 28 | 29 | double r1 = (-B + sqrt(D)) / (2 * A); 30 | double r2 = (-B - sqrt(D)) / (2 * A); 31 | 32 | cout << r1 << " " << r2 << endl; 33 | 34 | } 35 | // если дискриминант отрицателен, действительных корней нет 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /week-04/06-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() { 9 | ifstream input("input.txt"); 10 | 11 | int n, m; 12 | input >> n >> m; 13 | 14 | // перебираем строки 15 | for (int i = 0; i < n; ++i) { 16 | // перебираем столбцы 17 | for (int j = 0; j < m; ++j) { 18 | // считываем очередное число 19 | int x; 20 | input >> x; 21 | // пропускаем следующий символ 22 | input.ignore(1); 23 | // выводим число в поле ширины 10 24 | cout << setw(10) << x; 25 | // выводим пробел, если только этот столбец не последний 26 | if (j != m - 1) { 27 | cout << " "; 28 | } 29 | } 30 | // выводим перевод строки, если только эта строка не последняя 31 | if (i != n - 1) { 32 | cout << endl; 33 | } 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /week-02/05-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Перемещение строк #### 2 | 3 | Напишите функцию *MoveStrings*, которая принимает два вектора строк, *source* и *destination*, и дописывает все строки из первого вектора в конец второго. После выполнения функции вектор *source* должен оказаться пустым. 4 | 5 | *Чтобы очистить содержимое вектора, надо вызвать у него метод clear*: 6 | 7 | ```objectivec 8 | vector words = {"hey", "hi"}; 9 | words.clear(); 10 | // Теперь вектор words пуст 11 | ``` 12 | 13 | ##### Пример ##### 14 | ```objectivec 15 | vector source = {"a", "b", "c"}; 16 | vector destination = {"z"}; 17 | MoveStrings(source, destination); 18 | // source должен оказаться пустым 19 | // destination должен содержать строки "z", "a", "b", "c" именно в таком порядке 20 | ``` 21 | 22 | ##### Пояснение ##### 23 | В этой задаче на проверку вам надо прислать файл с реализацией функции *MoveStrings*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 24 | -------------------------------------------------------------------------------- /week-02/14-Programming-Assignment/Solution/buses2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() { 9 | int q; 10 | cin >> q; 11 | 12 | map, int> buses; 13 | 14 | for (int i = 0; i < q; ++i) { 15 | int n; 16 | cin >> n; 17 | vector stops(n); 18 | for (string& stop : stops) { 19 | cin >> stop; 20 | } 21 | 22 | // проверяем, не существует ли уже маршрут с таким набором остановок 23 | if (buses.count(stops) == 0) { 24 | 25 | // если не существует, нужно сохранить новый маршрут; 26 | // его номер на единицу больше текущего количества маршрутов 27 | const int new_number = buses.size() + 1; 28 | buses[stops] = new_number; 29 | cout << "New bus " << new_number << endl; 30 | 31 | } else { 32 | cout << "Already exists for " << buses[stops] << endl; 33 | } 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /week-03/02-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Сортировка без учёта регистра #### 2 | 3 | ##### Условие ##### 4 | В стандартном потоке дана одна строка, состоящая из числа *N* и следующих за ним *N* строк *S*. Между собой число и строки разделены пробелом. 5 | 6 | Отсортируйте строки *S* в лексикографическом порядке по возрастанию, игнорируя регистр букв, и выведите их в стандартный поток вывода. 7 | 8 | ##### Ограничения ##### 9 | 10 | * 0 <= N <= 1000 11 | * 1 <= |S| <= 15 12 | * Каждая строка S[i] может состоять из следующих символов: [0-9,a-z,A-Z] 13 | 14 | ##### Примеры ##### 15 | | stdin | stdout | 16 | |:------------------------------:|:------------------------------:| 17 | | 2 q A | A q | 18 | | 3 a C b | a b C | 19 | 20 | 21 | ##### Подсказка ##### 22 | Обратите внимание на [функцию](http://www.cplusplus.com/reference/cctype/tolower/) *[tolower](http://www.cplusplus.com/reference/cctype/tolower/)*. 23 | -------------------------------------------------------------------------------- /week-04/04-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Работа с файлами #### 2 | 3 | В этом задании вам предстоит написать две небольшие программы. Каждый пункт - отдельная задача, решение отправляйте в поле с соответствующим номером. 4 | 5 | ##### Часть 1 ##### 6 | Ваша программа должна считать содержимое файла *input.txt* и напечатать его на экран без изменений. Гарантируется, что содержимое файла *input.txt* заканчивается переводом строки. 7 | 8 | ###### Пример ###### 9 | **input.txt** 10 | ```objectivec 11 | Kepp calm 12 | and 13 | learn C++ 14 | ``` 15 | 16 | **stdout** 17 | ```objectivec 18 | Kepp calm 19 | and 20 | learn C++ 21 | ``` 22 | 23 | ##### Часть 2 ##### 24 | Снова считайте все содержимое файла *input.txt*, но на этот раз выведите его в файл *output.txt*. Точно так же гарантируется, что содержимое файла *input.txt* заканчивается переводом строки. 25 | 26 | ###### Пример ###### 27 | **input.txt** 28 | ```objectivec 29 | Kepp calm 30 | and 31 | learn C++ 32 | ``` 33 | 34 | **output.txt** 35 | ```objectivec 36 | Kepp calm 37 | and 38 | learn C++ 39 | ``` 40 | -------------------------------------------------------------------------------- /week-03/03-Practice-Programming-Assignment/sorted_strings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | class SortedStrings { 10 | public: 11 | void AddString(const string& s) { 12 | // добавить строку s в набор 13 | v.push_back(s); 14 | } 15 | vector GetSortedStrings() { 16 | // получить набор из всех добавленных строк в отсортированном порядке 17 | sort(begin(v), end(v)); 18 | return v; 19 | } 20 | private: 21 | // приватные поля 22 | vector v; 23 | }; 24 | 25 | void PrintSortedStrings(SortedStrings& strings) { 26 | for (const string& s : strings.GetSortedStrings()) { 27 | cout << s << " "; 28 | } 29 | cout << endl; 30 | } 31 | 32 | int main() { 33 | SortedStrings strings; 34 | 35 | strings.AddString("first"); 36 | strings.AddString("third"); 37 | strings.AddString("second"); 38 | PrintSortedStrings(strings); 39 | 40 | strings.AddString("second"); 41 | PrintSortedStrings(strings); 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /week-04/01-Programming-Assignment/lecture_title.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | struct Specialization { 8 | string value; 9 | explicit Specialization(string other_value) { 10 | value = other_value; 11 | } 12 | }; 13 | 14 | struct Course { 15 | string value; 16 | explicit Course(string other_value) { 17 | value = other_value; 18 | } 19 | }; 20 | 21 | struct Week { 22 | string value; 23 | explicit Week(string other_value) { 24 | value = other_value; 25 | } 26 | }; 27 | 28 | struct LectureTitle { 29 | string specialization; 30 | string course; 31 | string week; 32 | 33 | LectureTitle(Specialization other_specialization, Course other_course, Week other_week) { 34 | specialization = other_specialization.value; 35 | course = other_course.value; 36 | week = other_week.value; 37 | } 38 | }; 39 | 40 | int main() { 41 | 42 | LectureTitle title( 43 | Specialization("C++"), 44 | Course("White belt"), 45 | Week("4th") 46 | ); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/Source/rational_eq_add_sub.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Rational { 5 | // Вставьте сюда реализацию класса Rational из первой части 6 | }; 7 | 8 | // Реализуйте для класса Rational операторы ==, + и - 9 | 10 | int main() { 11 | { 12 | Rational r1(4, 6); 13 | Rational r2(2, 3); 14 | bool equal = r1 == r2; 15 | if (!equal) { 16 | cout << "4/6 != 2/3" << endl; 17 | return 1; 18 | } 19 | } 20 | 21 | { 22 | Rational a(2, 3); 23 | Rational b(4, 3); 24 | Rational c = a + b; 25 | bool equal = c == Rational(2, 1); 26 | if (!equal) { 27 | cout << "2/3 + 4/3 != 2" << endl; 28 | return 2; 29 | } 30 | } 31 | 32 | { 33 | Rational a(5, 7); 34 | Rational b(2, 9); 35 | Rational c = a - b; 36 | bool equal = c == Rational(31, 63); 37 | if (!equal) { 38 | cout << "5/7 - 2/9 != 31/63" << endl; 39 | return 3; 40 | } 41 | } 42 | 43 | cout << "OK" << endl; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /week-02/17-Programming-Assignment/synonyms.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | int main() { 10 | int q; 11 | cin >> q; 12 | map> words; 13 | 14 | for (int i = 0; i < q; ++i) { 15 | string operation_code; 16 | cin >> operation_code; 17 | if (operation_code == "ADD") { 18 | string word1, word2; 19 | cin >> word1 >> word2; 20 | set s1 = {word1}; 21 | set s2 = {word2}; 22 | words[word1].insert(word2); 23 | words[word2].insert(word1); 24 | } else if (operation_code == "COUNT") { 25 | string word; 26 | cin >> word; 27 | cout << words[word].size() << endl; 28 | } else if (operation_code == "CHECK") { 29 | string word1, word2; 30 | cin >> word1 >> word2; 31 | if (words[word1].count(word2) > 0) { 32 | cout << "YES" << endl; 33 | } else { 34 | cout << "NO" << endl; 35 | } 36 | } 37 | } 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /week-03/06-Practice-Programming-Assignment/reversible_string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | class ReversibleString { 10 | public: 11 | ReversibleString () { 12 | word = ""; 13 | } 14 | ReversibleString (const string& w) { 15 | word = w; 16 | } 17 | 18 | void Reverse() { 19 | vector v; 20 | 21 | for (int i = 0; i < word.size(); ++i) { 22 | v.push_back(word[i]); 23 | } 24 | 25 | reverse(begin(v), end(v)); 26 | 27 | word = ""; 28 | 29 | for (auto i : v) { 30 | word += i; 31 | } 32 | } 33 | 34 | string ToString() const { 35 | return word; 36 | } 37 | 38 | private: 39 | string word; 40 | }; 41 | 42 | int main() { 43 | ReversibleString s("live"); 44 | s.Reverse(); 45 | cout << s.ToString() << endl; 46 | 47 | s.Reverse(); 48 | const ReversibleString& s_ref = s; 49 | string tmp = s_ref.ToString(); 50 | cout << tmp << endl; 51 | 52 | ReversibleString empty; 53 | cout << '"' << empty.ToString() << '"' << endl; 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /week-03/02-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() { 9 | // считываем вектор строк 10 | int n; 11 | cin >> n; 12 | vector v(n); 13 | for (string& s : v) { 14 | cin >> s; 15 | } 16 | 17 | // сортируем 18 | sort(begin(v), end(v), 19 | // компаратор для сортировки — лямбда-функция, сравнивающая строки без учёта регистра 20 | [](const string& l, const string& r) { 21 | // сравниваем лексикографически... 22 | return lexicographical_compare( 23 | // ... все символы строки l ... 24 | begin(l), end(l), 25 | // ... со всеми символами строки r ... 26 | begin(r), end(r), 27 | // ..., используя в качестве компаратора сравнение отдельных символов без учёта регистра 28 | [](char cl, char cr) { return tolower(cl) < tolower(cr); } 29 | ); 30 | } 31 | ); 32 | 33 | // выводим отсортированный вектор 34 | for (const string& s : v) { 35 | cout << s << ' '; 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /week-04/01-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Структура LectureTitle #### 2 | 3 | Дана структура *LectureTitle*: 4 | ```objectivec 5 | struct LectureTitle { 6 | string specialization; 7 | string course; 8 | string week; 9 | }; 10 | ``` 11 | Допишите конструктор и структуры *Specialization*, *Course*, *Week* так, чтобы объект *LectureTitle* можно было создать с помощью кода 12 | ```objectivec 13 | LectureTitle title( 14 | Specialization("C++"), 15 | Course("White belt"), 16 | Week("4th") 17 | ); 18 | ``` 19 | но нельзя было с помощью следующих фрагментов кода: 20 | ```objectivec 21 | LectureTitle title("C++", "White belt", "4th"); 22 | 23 | LectureTitle title = {"C++", "White belt", "4th"}; 24 | 25 | LectureTitle title = {{"C++"}, {"White belt"}, {"4th"}}; 26 | 27 | LectureTitle title( 28 | Course("White belt"), 29 | Specialization("C++"), 30 | Week("4th") 31 | ); 32 | 33 | LectureTitle title( 34 | Specialization("C++"), 35 | Week("4th"), 36 | Course("White belt") 37 | ); 38 | ``` 39 | 40 | ##### Пояснение ##### 41 | В этой задаче вам надо прислать на проверку файл с реализацией необходимых классов. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 42 | -------------------------------------------------------------------------------- /week-04/12-Programming-Assignment/Source/time_server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | string AskTimeServer() { 7 | /* Для тестирования повставляйте сюда код, реализующий различное поведение этой функии: 8 | * нормальный возврат строкового значения 9 | * выброс исключения system_error 10 | * выброс другого исключения с сообщением. 11 | */ 12 | } 13 | 14 | class TimeServer { 15 | public: 16 | string GetCurrentTime() { 17 | /* Реализуйте этот метод: 18 | * если AskTimeServer() вернула значение, запишите его в LastFetchedTime и верните 19 | * если AskTimeServer() бросила исключение system_error, верните текущее значение 20 | поля LastFetchedTime 21 | * если AskTimeServer() бросила другое исключение, пробросьте его дальше. 22 | */ 23 | } 24 | 25 | private: 26 | string LastFetchedTime = "00:00:00"; 27 | }; 28 | 29 | int main() { 30 | // Меняя реализацию функции AskTimeServer, убедитесь, что это код работает корректно 31 | TimeServer ts; 32 | try { 33 | cout << ts.GetCurrentTime() << endl; 34 | } catch (exception& e) { 35 | cout << "Exception got: " << e.what() << endl; 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /week-02/03-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Отбор палиндромов #### 2 | 3 | Напишите функцию, которая 4 | 5 | * называется *PalindromFilter* 6 | * возвращает *vector* 7 | * принимает *vector* words и *int minLength* и возвращает все строки из вектора words, которые являются палиндромами и имеют длину не меньше *minLength* 8 | 9 | Входной вектор содержит не более 100 строк, длина каждой строки не больше 100 символов. 10 | 11 | ##### Примеры ##### 12 | 13 | | words | minLength | результат | 14 | |:------------------------------:|:------------------------------:|:------------------------------:| 15 | | abacaba, aba | 5 | abacaba | 16 | | abacaba, aba | 2 | abacaba, aba | 17 | | weew, bro, code | 4 | weew | 18 | 19 | ##### Пояснение ##### 20 | В этой задаче вам надо прислать на проверку файл с реализацией функции *PalindromFilter*, а также других функций, если это необходимо (*например, функции проверки на палиндром*). **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 21 | -------------------------------------------------------------------------------- /week-03/05-Programming-Assignment/Solution/README.md: -------------------------------------------------------------------------------- 1 | Отличие от предыдущей задачи состоит лишь в необходимости добавить метод *GetFullNameWithHistory*. Но для того, чтобы избежать дублирования кода в методах *GetFullName* и *GetFullNameWithHistory*, решение предыдущей задачи придётся значительно переработать. 2 | 3 | Напишем следующие вспомогательные функции: 4 | 5 | 1. Функцию *FindNamesHistory*, возвращающую по году и словарю «год → имя (фамилия)» всю историю изменений имени (фамилии) к этому году в виде вектора строк. 6 | 2. Функцию *BuildJoinedName*, по истории изменений имени (фамилии) возвращающую эту историю в виде единой строки: сначала последнее имя, затем в круглых скобках через запятую все предыдущие имена. 7 | 3. Функцию *BuildFullName*, по имени и фамилии (возможно, неизвестным, то есть пустым) возвращающую полное имя в требуемом формате. В прошлой задаче этот код находился непосредственно в методе *GetFullName*, теперь же он понадобился и в методе *GetFullNameWithHistory* — потому мы и выделили его в отдельную функцию. 8 | 9 | Кроме того, напишем короткие вспомогательные приватные методы *FindFirstNamesHistory* и *FindLastNamesHistory*, с помощью функции *FindNamesHistory* возвращающие по данному году историю изменений имени или фамилии. 10 | 11 | В методах *GetFullName* и *GetFullNameWithHistory* останется лишь аккуратно вызвать описанные выше функции и методы. -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/Source/rational_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | class Rational { 8 | // Вставьте сюда реализацию класса Rational из первой части 9 | }; 10 | 11 | // Вставьте сюда реализацию operator == для класса Rational из второй части 12 | 13 | // Реализуйте для класса Rational оператор(ы), необходимые для использования его 14 | // в качестве ключа map'а и элемента set'а 15 | 16 | int main() { 17 | { 18 | const set rs = {{1, 2}, {1, 25}, {3, 4}, {3, 4}, {1, 2}}; 19 | if (rs.size() != 3) { 20 | cout << "Wrong amount of items in the set" << endl; 21 | return 1; 22 | } 23 | 24 | vector v; 25 | for (auto x : rs) { 26 | v.push_back(x); 27 | } 28 | if (v != vector{{1, 25}, {1, 2}, {3, 4}}) { 29 | cout << "Rationals comparison works incorrectly" << endl; 30 | return 2; 31 | } 32 | } 33 | 34 | { 35 | map count; 36 | ++count[{1, 2}]; 37 | ++count[{1, 2}]; 38 | 39 | ++count[{2, 3}]; 40 | 41 | if (count.size() != 2) { 42 | cout << "Wrong amount of items in the map" << endl; 43 | return 3; 44 | } 45 | } 46 | 47 | cout << "OK" << endl; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /week-04/11-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Калькулятор обыкновенных дробей #### 2 | 3 | Итак, теперь у нас с вами есть полноценный тип для представления обыкновенных дробей: класс *Rational* интегрирован в язык с помощью перегрузки операторов и не позволяет выполнять некорректные операции за счёт выбрасывания исключений. Давайте на основе класса *Rational* создадим простой калькулятор для обыкновенных дробей. 4 | 5 | Вам надо написать программу, которая считывает из стандартного ввода одну строку в формате ***ДРОБЬ_1 операция ДРОБЬ_2***. *ДРОБЬ_1* и *ДРОБЬ_2* имеют формат *X/Y*, где *X* — целое, а *Y* — целое неотрицательное число. операция — это один из символов *'+', '-', '*', '/'*. 6 | 7 | Если *ДРОБЬ_1* или *ДРОБЬ_2* является некорректной обыкновенной дробью, ваша программа должна вывести в стандартный вывод сообщение *"Invalid argument"*. Если считанная операция — это деление на ноль, выведите в стандартный вывод сообщение *"Division by zero"*. В противном случае выведите результат операции. 8 | 9 | ##### Пример ##### 10 | | stdin | stdout | 11 | |:------------------------------:|:------------------------------:| 12 | | 1/2 + 1/3 | 5/6 | 13 | | 1/2 + 5/0 | Invalid argument | 14 | | 4/5 / 0/8 | Division by zero | 15 | -------------------------------------------------------------------------------- /week-03/03-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Отсортированные строки #### 2 | 3 | Реализуйте класс, поддерживающий набор строк в отсортированном порядке. Класс должен содержать два публичных метода: 4 | ```objectivec 5 | class SortedStrings { 6 | public: 7 | void AddString(const string& s) { 8 | // добавить строку s в набор 9 | } 10 | vector GetSortedStrings() { 11 | // получить набор из всех добавленных строк в отсортированном порядке 12 | } 13 | private: 14 | // приватные поля 15 | }; 16 | ``` 17 | 18 | ##### Пример ##### 19 | ###### Код ###### 20 | ```objectivec 21 | void PrintSortedStrings(SortedStrings& strings) { 22 | for (const string& s : strings.GetSortedStrings()) { 23 | cout << s << " "; 24 | } 25 | cout << endl; 26 | } 27 | 28 | int main() { 29 | SortedStrings strings; 30 | 31 | strings.AddString("first"); 32 | strings.AddString("third"); 33 | strings.AddString("second"); 34 | PrintSortedStrings(strings); 35 | 36 | strings.AddString("second"); 37 | PrintSortedStrings(strings); 38 | 39 | return 0; 40 | } 41 | ``` 42 | 43 | ###### Вывод ###### 44 | ```objectivec 45 | first second third 46 | first second second third 47 | ``` 48 | 49 | ##### Пояснение ##### 50 | В этой задаче вам надо прислать файл с реализацией класса *SortedStrings*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 51 | -------------------------------------------------------------------------------- /week-02/17-Programming-Assignment/Solution/synonyms.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() { 9 | int q; 10 | cin >> q; 11 | 12 | map> synonyms; 13 | 14 | for (int i = 0; i < q; ++i) { 15 | string operation_code; 16 | cin >> operation_code; 17 | 18 | if (operation_code == "ADD") { 19 | 20 | string first_word, second_word; 21 | cin >> first_word >> second_word; 22 | 23 | // второе слово добавляем в список синонимов первого... 24 | synonyms[first_word].insert(second_word); 25 | // и наоборот 26 | synonyms[second_word].insert(first_word); 27 | 28 | } else if (operation_code == "COUNT") { 29 | 30 | string word; 31 | cin >> word; 32 | cout << synonyms[word].size() << endl; 33 | 34 | } else if (operation_code == "CHECK") { 35 | 36 | string first_word, second_word; 37 | cin >> first_word >> second_word; 38 | 39 | // ищём второе слово во множестве синонимов первого 40 | // (можно было сделать и наоборот) 41 | if (synonyms[first_word].count(second_word) == 1) { 42 | cout << "YES" << endl; 43 | } else { 44 | cout << "NO" << endl; 45 | } 46 | 47 | } 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /week-04/07-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Список студентов #### 2 | 3 | Определите структуру "Студент" с полями имя, фамилия, дата, месяц и год рождения. Создайте вектор из таких структур, заполните его из входных данных и затем по запросам выведите нужные поля. 4 | 5 | ##### Формат ввода ##### 6 | Первая строка содержит одно целое число *N* от 0 до 10000 - число студентов. 7 | 8 | Далее идут *N* строк, каждая из которых содержит две строки длиной от 1 до 15 символов - имя и фамилия очередного студента, и три целых числа от 0 до 1000000000 - день, месяц и год рождения. 9 | 10 | Следующая строка содержит одно целое число *M* от 0 до 10000 - число запросов. 11 | 12 | Следующие *M* строк содержат строку длиной от 1 до 15 символов - запрос, и целое число от 0 до 1000000000 - номер студента (нумерация начинается с 1). 13 | 14 | ##### Формат вывода ##### 15 | Для запроса вида **"name K"**, где *K* от 1 до *N*, выведите через пробел имя и фамилию *K*-го студента. 16 | 17 | Для запроса вида **"date K"**, где *K* от 1 до *N*, выведите через точку число, месяц и год рождения *K*-го студента. 18 | 19 | Для остальных запросов выведите **"bad request"**. 20 | 21 | ##### Пример ввода ##### 22 | ```objectivec 23 | 3 24 | Ivan Ivanov 1 1 1901 25 | Petr Petrox 2 2 1902 26 | Alexander Sidorov 3 3 1903 27 | 3 28 | name 1 29 | date 3 30 | mark 5 31 | ``` 32 | ##### Пример вывода ##### 33 | ```objectivec 34 | Ivan Ivanov 35 | 3.3.1903 36 | bad request 37 | ``` 38 | -------------------------------------------------------------------------------- /week-04/12-Programming-Assignment/time_server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | string AskTimeServer() { 9 | /* Для тестирования повставляйте сюда код, реализующий различное поведение этой функии: 10 | * нормальный возврат строкового значения 11 | * выброс исключения system_error 12 | * выброс другого исключения с сообщением. 13 | */ 14 | } 15 | 16 | class TimeServer { 17 | public: 18 | string GetCurrentTime() { 19 | /* Реализуйте этот метод: 20 | * если AskTimeServer() вернула значение, запишите его в LastFetchedTime и верните 21 | * если AskTimeServer() бросила исключение system_error, верните текущее значение 22 | поля LastFetchedTime 23 | * если AskTimeServer() бросила другое исключение, пробросьте его дальше. 24 | */ 25 | try { 26 | LastFetchedTime = AskTimeServer(); 27 | return LastFetchedTime; 28 | } catch (system_error& se) { 29 | return LastFetchedTime; 30 | } 31 | } 32 | 33 | private: 34 | string LastFetchedTime = "00:00:00"; 35 | }; 36 | 37 | int main() { 38 | // Меняя реализацию функции AskTimeServer, убедитесь, что это код работает корректно 39 | TimeServer ts; 40 | try { 41 | cout << ts.GetCurrentTime() << endl; 42 | } catch (exception& e) { 43 | cout << "Exception got: " << e.what() << endl; 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /week-02/11-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Анаграммы #### 2 | 3 | Слова называются *анаграммами* друг друга, если одно из них можно получить перестановкой букв в другом. Например, слово «eat» можно получить перестановкой букв слова «tea», поэтому эти слова являются анаграммами друг друга. Даны пары слов, проверьте для каждой из них, являются ли слова этой пары анаграммами друг друга. 4 | 5 | ##### Указание ##### 6 | Один из способов проверки того, являются ли слова анаграммами друг друга, заключается в следующем. Для каждого слова с помощью словаря подсчитаем, сколько раз в нём встречается каждая буква. Если для обоих слов эти словари равны (а это проверяется с помощью обычного оператора ==), то слова являются анаграммами друг друга, в противном случае не являются. 7 | 8 | При этом построение такого словаря по слову удобно вынести в отдельную функцию *BuildCharCounters*. 9 | 10 | ##### Формат ввода ##### 11 | Сначала дано число пар слов _N_, затем в _N_ строках содержатся пары слов, которые необходимо проверить. Гарантируется, что все слова состоят лишь из строчных латинских букв. 12 | 13 | ##### Формат вывода ##### 14 | Выведите _N_ строк: для каждой введённой пары слов **YES**, если эти слова являются анаграммами, и **NO** в противном случае. 15 | 16 | ##### Пример ##### 17 | ###### Ввод ###### 18 | ```objectivec 19 | 3 20 | eat tea 21 | find search 22 | master stream 23 | ``` 24 | 25 | ###### Вывод ###### 26 | ```objectivec 27 | YES 28 | NO 29 | YES 30 | ``` 31 | -------------------------------------------------------------------------------- /week-03/07-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Имена и фамилии — 3 #### 2 | 3 | Дополните класс *Person* из задачи «Имена и фамилии — 2» конструктором, позволяющим задать имя и фамилию человека при рождении, а также сам год рождения. Класс не должен иметь конструктора по умолчанию. 4 | 5 | При получении на вход года, который меньше года рождения: 6 | 7 | * методы *GetFullName* и *GetFullNameWithHistory* должны отдавать **"No person"**; 8 | * методы *ChangeFirstName* и *ChangeLastName* должны игнорировать запрос. 9 | * Кроме того, необходимо объявить константными все методы, которые по сути ими являются. 10 | 11 | ##### Пример ##### 12 | ###### Код ###### 13 | ```objectivec 14 | int main() { 15 | Person person("Polina", "Sergeeva", 1960); 16 | for (int year : {1959, 1960}) { 17 | cout << person.GetFullNameWithHistory(year) << endl; 18 | } 19 | 20 | person.ChangeFirstName(1965, "Appolinaria"); 21 | person.ChangeLastName(1967, "Ivanova"); 22 | for (int year : {1965, 1967}) { 23 | cout << person.GetFullNameWithHistory(year) << endl; 24 | } 25 | 26 | return 0; 27 | } 28 | ``` 29 | 30 | ###### Вывод ###### 31 | ```objectivec 32 | No person 33 | Polina Sergeeva 34 | Appolinaria (Polina) Sergeeva 35 | Appolinaria (Polina) Ivanova (Sergeeva) 36 | ``` 37 | 38 | ##### Пояснение ##### 39 | В этой задаче вам надо прислать на проверку файл с реализацией класса *Person*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 40 | -------------------------------------------------------------------------------- /week-02/09-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Очередь #### 2 | 3 | Люди стоят в очереди, но никогда не уходят из её начала, зато могут приходить в конец и уходить оттуда. Более того, иногда некоторые люди могут прекращать и начинать беспокоиться из-за того, что очередь не продвигается. 4 | 5 | Реализуйте обработку следующих операций над очередью: 6 | 7 | * **WORRY *i***: пометить ***i***-го человека с начала очереди (в нумерации с 0) как беспокоящегося; 8 | * **QUIET *i***: пометить ***i***-го человека как успокоившегося; 9 | * **COME *k***: добавить ***k*** спокойных человек в конец очереди; 10 | * **COME *-k***: убрать ***k*** человек из конца очереди; 11 | * **WORRY_COUNT**: узнать количество беспокоящихся людей в очереди. 12 | 13 | Изначально очередь пуста. 14 | 15 | ##### Формат ввода ##### 16 | Количество операций *Q*, затем описания операций. 17 | 18 | Для каждой операции **WORRY *i*** и **QUIET *i*** гарантируется, что человек с номером ***i*** существует в очереди на момент операции. 19 | 20 | Для каждой операции **COME *-k*** гарантируется, что ***k*** не больше текущего размера очереди. 21 | 22 | ##### Формат вывода ##### 23 | Для каждой операции **WORRY_COUNT** выведите одно целое число — количество беспокоящихся людей в очереди. 24 | 25 | ##### Пример ##### 26 | ###### Ввод ###### 27 | ```objectivec 28 | 8 29 | COME 5 30 | WORRY 1 31 | WORRY 4 32 | COME -2 33 | WORRY_COUNT 34 | COME 3 35 | WORRY 3 36 | WORRY_COUNT 37 | ``` 38 | 39 | ###### Вывод ###### 40 | ```objectivec 41 | 1 42 | 2 43 | ``` 44 | -------------------------------------------------------------------------------- /week-04/10-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Исключения в классе Rational #### 2 | 3 | Вспомним класс *Rational*, который мы реализовали в задачах, посвящённых перегрузке операторов. Там специально говорилось, что в тестах объекты класса *Rational* никогда не создаются с нулевым знаменателем и никогда не выполняется деление на ноль. Настало время избавиться от этого ограничения и научиться обрабатывать нулевой знаменатель и деление на ноль. В этой задаче вам предстоит это сделать. 4 | 5 | Поменяйте реализацию конструктора класса *Rational* так, чтобы он выбрасывал исключение *invalid_argument*, если знаменатель равен нулю. Кроме того, переделайте реализацию оператора деления для класса *Rational* так, чтобы он выбрасывал исключение *domain_error*, если делитель равен нулю. 6 | 7 | Напомним, что вам надо реализовать интерфейс 8 | ```objectivec 9 | class Rational { 10 | public: 11 | Rational(); 12 | Rational(int numerator, int denominator); 13 | 14 | int Numerator() const; 15 | int Denominator() const; 16 | }; 17 | ``` 18 | и оператор деления для класса Rational 19 | ```objectivec 20 | Rational operator / (const Rational& lhs, const Rational& rhs); 21 | ``` 22 | 23 | Так же, как и в задачах на перегрузку операторов, вам будет предложен файл с заготовкой кода. Функция *main* в этом файле содержит ряд юнит-тестов, которые позволят вам проверить свою реализацию. При проверке вашего решения оно будет тестироваться на более полном наборе тестов, так что успешное прохождение всех юнит-тестов не гарантирует, что ваша реализация будет зачтена. -------------------------------------------------------------------------------- /week-04/07-Practice-Programming-Assignment/students.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | struct Student { 9 | Student(string other_firstname, string other_lastname, int other_day, int other_month, int other_year) { 10 | firstname = other_firstname; 11 | lastname = other_lastname; 12 | day = other_day; 13 | month = other_month; 14 | year = other_year; 15 | } 16 | string firstname = ""; 17 | string lastname = ""; 18 | int day = 0; 19 | int month = 0; 20 | int year = 0; 21 | }; 22 | 23 | int main() { 24 | string firstname, lastname; 25 | int day, month, year; 26 | vector v; 27 | 28 | int n; 29 | cin >> n; 30 | 31 | for (int i = 0; i < n; ++i) { 32 | cin >> firstname >> lastname >> day >> month >> year; 33 | Student student{firstname, lastname, day, month, year}; 34 | v.push_back(student); 35 | } 36 | 37 | int m; 38 | cin >> m; 39 | 40 | for (int j = 0; j < m; ++j) { 41 | string operation; 42 | int k; 43 | cin >> operation >> k; 44 | if (operation == "name" && k > 0 && k <= v.size()) { 45 | cout << v[k-1].firstname << " " << v[k-1].lastname << endl; 46 | } else if (operation == "date" && k > 0 && k <= v.size()) { 47 | cout << v[k-1].day << "." << v[k-1].month << "." << v[k-1].year << endl; 48 | } else { 49 | cout << "bad request" << endl; 50 | } 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /week-02/09-Programming-Assignment/Solution/queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | int q; 9 | cin >> q; 10 | vector is_nervous; 11 | 12 | for (int i = 0; i < q; ++i) { 13 | string operation_code; 14 | cin >> operation_code; 15 | 16 | if (operation_code == "WORRY_COUNT") { 17 | 18 | // подсчитываем количество элементов в векторе is_nervous, равных true 19 | cout << count(begin(is_nervous), end(is_nervous), true) << endl; 20 | 21 | } else { 22 | if (operation_code == "WORRY" || operation_code == "QUIET") { 23 | 24 | int person_index; 25 | cin >> person_index; 26 | 27 | // выражение в скобках имеет тип bool и равно true для запроса WORRY, 28 | // поэтому is_nervous[person_index] станет равным false или true 29 | // в зависимости от operation_code 30 | is_nervous[person_index] = (operation_code == "WORRY"); 31 | 32 | } else if (operation_code == "COME") { 33 | 34 | int person_count; 35 | cin >> person_count; 36 | 37 | // метод resize может как уменьшать размер вектора, так и увеличивать, 38 | // поэтому специально рассматривать случаи с положительным 39 | // и отрицательным person_count не нужно 40 | is_nervous.resize(is_nervous.size() + person_count, false); 41 | 42 | } 43 | } 44 | } 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /week-02/17-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Синонимы #### 2 | 3 | Два слова называются *синонимами* друг друга, если они имеют похожие значения. Реализуйте следующие операции над словарём синонимов: 4 | 5 | * **ADD *word1* *word2*** — добавить в словарь пару синонимов (***word1, word2***). 6 | * **COUNT *word*** — узнать количество синонимов слова ***word***. 7 | * **CHECK *word1* *word2*** — проверить, являются ли слова ***word1*** и ***word2*** синонимами. Слова ***word1*** и ***word2*** считаются синонимами, если среди запросов **ADD** был хотя бы один запрос **ADD *word1 word2*** или **ADD *word2 word1***. 8 | 9 | ##### Формат ввода ##### 10 | Сначала вводится количество запросов *Q*, затем *Q* строк с описаниями запросов. Гарантируется, что в каждом запросе **CHECK** и **ADD** слова ***word1*** и ***word2*** различны. Все слова состоят лишь из латинских букв, цифр и символов подчёркивания. 11 | 12 | ##### Формат вывода ##### 13 | Для каждого запроса в соответствующей строке выведите ответ на него: 14 | 15 | * В ответ на запрос **COUNT *word*** выведите единственное целое число — количество синонимов слова ***word***. 16 | * В ответ на запрос **CHECK *word1 word2*** выведите строку **YES**, если ***word1*** и ***word2*** являются синонимами, и **NO** в противном случае. 17 | 18 | ##### Пример ##### 19 | ###### Ввод ###### 20 | ```objectivec 21 | 8 22 | ADD program code 23 | COUNT cipher 24 | ADD code cipher 25 | COUNT code 26 | COUNT program 27 | CHECK code program 28 | CHECK program cipher 29 | CHECK cpp java 30 | ``` 31 | 32 | ###### Вывод ###### 33 | ```objectivec 34 | 0 35 | 2 36 | 1 37 | YES 38 | NO 39 | NO 40 | ``` 41 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/Source/rational_io.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Rational { 6 | // Вставьте сюда реализацию класса Rational из первой части 7 | }; 8 | 9 | // Вставьте сюда реализацию operator == для класса Rational из второй части 10 | 11 | // Реализуйте для класса Rational операторы << и >> 12 | 13 | int main() { 14 | { 15 | ostringstream output; 16 | output << Rational(-6, 8); 17 | if (output.str() != "-3/4") { 18 | cout << "Rational(-6, 8) should be written as \"-3/4\"" << endl; 19 | return 1; 20 | } 21 | } 22 | 23 | { 24 | istringstream input("5/7"); 25 | Rational r; 26 | input >> r; 27 | bool equal = r == Rational(5, 7); 28 | if (!equal) { 29 | cout << "5/7 is incorrectly read as " << r << endl; 30 | return 2; 31 | } 32 | } 33 | 34 | { 35 | istringstream input("5/7 10/8"); 36 | Rational r1, r2; 37 | input >> r1 >> r2; 38 | bool correct = r1 == Rational(5, 7) && r2 == Rational(5, 4); 39 | if (!correct) { 40 | cout << "Multiple values are read incorrectly: " << r1 << " " << r2 << endl; 41 | return 3; 42 | } 43 | 44 | input >> r1; 45 | input >> r2; 46 | correct = r1 == Rational(5, 7) && r2 == Rational(5, 4); 47 | if (!correct) { 48 | cout << "Read from empty stream shouldn't change arguments: " << r1 << " " << r2 << endl; 49 | return 4; 50 | } 51 | } 52 | 53 | cout << "OK" << endl; 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /week-04/03-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class FunctionPart { 7 | public: 8 | FunctionPart(char new_operation, double new_value) { 9 | operation = new_operation; 10 | value = new_value; 11 | } 12 | double Apply(double source_value) const { 13 | if (operation == '+') { 14 | return source_value + value; 15 | } else if (operation == '-') { 16 | return source_value - value; 17 | } else if (operation == '*') { 18 | return source_value * value; 19 | } else { // operation == '/' 20 | return source_value / value; 21 | } 22 | } 23 | void Invert() { 24 | if (operation == '+') { 25 | operation = '-'; 26 | } else if (operation == '-') { 27 | operation = '+'; 28 | } else if (operation == '*') { 29 | operation = '/'; 30 | } else { // operation == '/' 31 | operation = '*'; 32 | } 33 | } 34 | private: 35 | char operation; 36 | double value; 37 | }; 38 | 39 | class Function { 40 | public: 41 | void AddPart(char operation, double value) { 42 | parts.push_back({operation, value}); 43 | } 44 | double Apply(double value) const { 45 | for (const FunctionPart& part : parts) { 46 | value = part.Apply(value); 47 | } 48 | return value; 49 | } 50 | void Invert() { 51 | for (FunctionPart& part : parts) { 52 | part.Invert(); 53 | } 54 | reverse(begin(parts), end(parts)); 55 | } 56 | private: 57 | vector parts; 58 | }; 59 | -------------------------------------------------------------------------------- /week-04/10-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int GreatestCommonDivisor(int a, int b) { 7 | if (b == 0) { 8 | return a; 9 | } else { 10 | return GreatestCommonDivisor(b, a % b); 11 | } 12 | } 13 | 14 | class Rational { 15 | public: 16 | Rational() { 17 | numerator = 0; 18 | denominator = 1; 19 | } 20 | Rational(int new_numerator, int new_denominator) { 21 | if (new_denominator == 0) { 22 | // бросаем исключение в случае нулевого знаменателя 23 | throw invalid_argument(""); 24 | } 25 | const int gcd = GreatestCommonDivisor(new_numerator, new_denominator); 26 | numerator = new_numerator / gcd; 27 | denominator = new_denominator / gcd; 28 | if (denominator < 0) { 29 | denominator = -denominator; 30 | numerator = -numerator; 31 | } 32 | } 33 | 34 | int Numerator() const { 35 | return numerator; 36 | } 37 | 38 | int Denominator() const { 39 | return denominator; 40 | } 41 | 42 | private: 43 | int numerator; 44 | int denominator; 45 | }; 46 | 47 | Rational operator * (const Rational& lhs, const Rational& rhs) { 48 | return { 49 | lhs.Numerator() * rhs.Numerator(), 50 | lhs.Denominator() * rhs.Denominator() 51 | }; 52 | } 53 | 54 | Rational operator / (const Rational& lhs, const Rational& rhs) { 55 | // проверяем делитель на 0 (что равносильно проверке на 0 его числителя) 56 | if (rhs.Numerator() == 0) { 57 | throw domain_error(""); 58 | } 59 | return lhs * Rational(rhs.Denominator(), rhs.Numerator()); 60 | } -------------------------------------------------------------------------------- /week-02/10-Programming-Assignment/MonthlyBusiness.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | int main() { 9 | int m = 0; 10 | vector days_in_months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 11 | int q; 12 | cin >> q; 13 | vector> v(31, vector()); 14 | 15 | for (int i = 0; i < q; ++i) { 16 | string operation_code; 17 | cin >> operation_code; 18 | if (operation_code == "ADD") { 19 | string s; 20 | int i; 21 | cin >> i; 22 | cin >> s; 23 | v[i-1].push_back(s); 24 | } else if (operation_code == "DUMP") { 25 | int i; 26 | cin >> i; 27 | cout << v[i-1].size(); 28 | for (string s: v[i-1]) { 29 | cout << " " << s; 30 | } 31 | cout << endl; 32 | } else if (operation_code == "NEXT") { 33 | m += 1; 34 | if (m == 12) { 35 | m = 0; 36 | } 37 | if (m == 0) { 38 | } else { 39 | if (days_in_months[m] == 28) { 40 | v[27].insert(end(v[27]), begin(v[28]), end(v[28])); 41 | v[28].clear(); 42 | v[27].insert(end(v[27]), begin(v[29]), end(v[29])); 43 | v[29].clear(); 44 | v[27].insert(end(v[27]), begin(v[30]), end(v[30])); 45 | v[30].clear(); 46 | } else if (days_in_months[m] == 30) { 47 | v[29].insert(end(v[29]), begin(v[30]), end(v[30])); 48 | v[30].clear(); 49 | } 50 | } 51 | } 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /week-04/03-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Обратимая функция с умножением и делением #### 2 | 3 | Добавьте в класс *Function* из задачи «Обратимая функция» обработку умножения (__'*'__) и деления (__'/'__). Гарантируется отсутствие элементарных операций умножения и деления на 0. 4 | 5 | ##### Пример ##### 6 | ###### Код ###### 7 | ```objectivec 8 | struct Image { 9 | double quality; 10 | double freshness; 11 | double rating; 12 | }; 13 | 14 | struct Params { 15 | double a; 16 | double b; 17 | double c; 18 | }; 19 | 20 | Function MakeWeightFunction(const Params& params, 21 | const Image& image) { 22 | Function function; 23 | function.AddPart('*', params.a); 24 | function.AddPart('-', image.freshness * params.b); 25 | function.AddPart('+', image.rating * params.c); 26 | return function; 27 | } 28 | 29 | double ComputeImageWeight(const Params& params, const Image& image) { 30 | Function function = MakeWeightFunction(params, image); 31 | return function.Apply(image.quality); 32 | } 33 | 34 | double ComputeQualityByWeight(const Params& params, 35 | const Image& image, 36 | double weight) { 37 | Function function = MakeWeightFunction(params, image); 38 | function.Invert(); 39 | return function.Apply(weight); 40 | } 41 | 42 | int main() { 43 | Image image = {10, 2, 6}; 44 | Params params = {4, 2, 6}; 45 | cout << ComputeImageWeight(params, image) << endl; 46 | cout << ComputeQualityByWeight(params, image, 52) << endl; 47 | return 0; 48 | } 49 | ``` 50 | ###### Вывод ###### 51 | ```objectivec 52 | 72 53 | 5 54 | ``` 55 | 56 | ##### Пояснение ##### 57 | В этой задаче вам надо прислать на проверку файл с реализацией необходимых классов. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 58 | -------------------------------------------------------------------------------- /week-03/04-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // если имя неизвестно, возвращает пустую строку 5 | string FindNameByYear(const map& names, int year) { 6 | string name; // изначально имя неизвестно 7 | 8 | // перебираем всю историю по возрастанию ключа словаря, то есть в хронологическом порядке 9 | for (const auto& item : names) { 10 | // если очередной год не больше данного, обновляем имя 11 | if (item.first <= year) { 12 | name = item.second; 13 | } else { 14 | // иначе пора остановиться, так как эта запись и все последующие относятся к будущему 15 | break; 16 | } 17 | } 18 | 19 | return name; 20 | } 21 | 22 | class Person { 23 | public: 24 | void ChangeFirstName(int year, const string& first_name) { 25 | first_names[year] = first_name; 26 | } 27 | void ChangeLastName(int year, const string& last_name) { 28 | last_names[year] = last_name; 29 | } 30 | string GetFullName(int year) { 31 | // получаем имя и фамилию по состоянию на год year 32 | const string first_name = FindNameByYear(first_names, year); 33 | const string last_name = FindNameByYear(last_names, year); 34 | 35 | // если и имя, и фамилия неизвестны 36 | if (first_name.empty() && last_name.empty()) { 37 | return "Incognito"; 38 | 39 | // если неизвестно только имя 40 | } else if (first_name.empty()) { 41 | return last_name + " with unknown first name"; 42 | 43 | // если неизвестна только фамилия 44 | } else if (last_name.empty()) { 45 | return first_name + " with unknown last name"; 46 | 47 | // если известны и имя, и фамилия 48 | } else { 49 | return first_name + " " + last_name; 50 | } 51 | } 52 | 53 | private: 54 | map first_names; 55 | map last_names; 56 | }; 57 | -------------------------------------------------------------------------------- /week-04/02-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Обратимая функция #### 2 | 3 | Реализуйте рассказанный на лекции класс **Function**, позволяющий создавать, вычислять и инвертировать функцию, состоящую из следующих элементарных операций: 4 | 5 | * прибавить вещественное число *x*; 6 | * вычесть вещественное число *x*. 7 | 8 | При этом необходимо объявить константными все методы, которые по сути такими являются. 9 | 10 | ##### Пример ##### 11 | ###### Код ###### 12 | ```objectivec 13 | struct Image { 14 | double quality; 15 | double freshness; 16 | double rating; 17 | }; 18 | 19 | struct Params { 20 | double a; 21 | double b; 22 | double c; 23 | }; 24 | 25 | Function MakeWeightFunction(const Params& params, 26 | const Image& image) { 27 | Function function; 28 | function.AddPart('-', image.freshness * params.a + params.b); 29 | function.AddPart('+', image.rating * params.c); 30 | return function; 31 | } 32 | 33 | double ComputeImageWeight(const Params& params, const Image& image) { 34 | Function function = MakeWeightFunction(params, image); 35 | return function.Apply(image.quality); 36 | } 37 | 38 | double ComputeQualityByWeight(const Params& params, 39 | const Image& image, 40 | double weight) { 41 | Function function = MakeWeightFunction(params, image); 42 | function.Invert(); 43 | return function.Apply(weight); 44 | } 45 | 46 | int main() { 47 | Image image = {10, 2, 6}; 48 | Params params = {4, 2, 6}; 49 | cout << ComputeImageWeight(params, image) << endl; 50 | cout << ComputeQualityByWeight(params, image, 46) << endl; 51 | return 0; 52 | } 53 | ``` 54 | ###### Вывод ###### 55 | ```objectivec 56 | 36 57 | 20 58 | ``` 59 | 60 | ##### Пояснение ###### 61 | В этой задаче вам надо прислать на проверку файл с реализацией необходимых классов. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 62 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/Source/rational_interface.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Rational { 5 | public: 6 | Rational() { 7 | // Реализуйте конструктор по умолчанию 8 | } 9 | 10 | Rational(int numerator, int denominator) { 11 | // Реализуйте конструктор 12 | } 13 | 14 | int Numerator() const { 15 | // Реализуйте этот метод 16 | } 17 | 18 | int Denominator() const { 19 | // Реализуйте этот метод 20 | } 21 | 22 | private: 23 | // Добавьте поля 24 | }; 25 | 26 | int main() { 27 | { 28 | const Rational r(3, 10); 29 | if (r.Numerator() != 3 || r.Denominator() != 10) { 30 | cout << "Rational(3, 10) != 3/10" << endl; 31 | return 1; 32 | } 33 | } 34 | 35 | { 36 | const Rational r(8, 12); 37 | if (r.Numerator() != 2 || r.Denominator() != 3) { 38 | cout << "Rational(8, 12) != 2/3" << endl; 39 | return 2; 40 | } 41 | } 42 | 43 | { 44 | const Rational r(-4, 6); 45 | if (r.Numerator() != -2 || r.Denominator() != 3) { 46 | cout << "Rational(-4, 6) != -2/3" << endl; 47 | return 3; 48 | } 49 | } 50 | 51 | { 52 | const Rational r(4, -6); 53 | if (r.Numerator() != -2 || r.Denominator() != 3) { 54 | cout << "Rational(4, -6) != -2/3" << endl; 55 | return 3; 56 | } 57 | } 58 | 59 | { 60 | const Rational r(0, 15); 61 | if (r.Numerator() != 0 || r.Denominator() != 1) { 62 | cout << "Rational(0, 15) != 0/1" << endl; 63 | return 4; 64 | } 65 | } 66 | 67 | { 68 | const Rational defaultConstructed; 69 | if (defaultConstructed.Numerator() != 0 || defaultConstructed.Denominator() != 1) { 70 | cout << "Rational() != 0/1" << endl; 71 | return 5; 72 | } 73 | } 74 | 75 | cout << "OK" << endl; 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /week-02/10-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Ежемесячные дела #### 2 | 3 | У каждого из нас есть ежемесячные дела, каждое из которых нужно выполнять в конкретный день каждого месяца: оплата счетов за электричество, абонентская плата за связь и пр. Вам нужно реализовать работу со списком таких дел, а именно, обработку следующих операций: 4 | 5 | **ADD *i s*** 6 | 7 | Добавить дело с названием ***s*** в день ***i***. 8 | 9 | **NEXT** 10 | 11 | Закончить текущий месяц и начать новый. Если новый месяц имеет больше дней, чем текущий, добавленные дни изначально не будут содержать дел. Если же в новом месяце меньше дней, дела со всех удаляемых дней необходимо будет переместить на последний день нового месяца. 12 | 13 | Обратите внимание, что количество команд этого типа может превышать 11. 14 | 15 | **DUMP *i*** 16 | 17 | Вывести все дела в день ***i***. 18 | 19 | Изначально текущим месяцем считается январь. Количества дней в месяцах соответствуют Григорианскому календарю с той лишь разницей, что в феврале всегда 28 дней. 20 | 21 | ##### Указание ##### 22 | Для дописывания всех элементов вектора *v2* в конец вектора *v1* удобно использовать метод *insert*: 23 | 24 | ```objectivec 25 | v1.insert(end(v1), begin(v2), end(v2)); 26 | ``` 27 | 28 | ##### Формат ввода ##### 29 | Сначала число операций *Q*, затем описания операций. 30 | 31 | Названия дел ***s*** уникальны и состоят только из латинских букв, цифр и символов подчёркивания. Номера дней ***i*** являются целыми числами и нумеруются от 1 до размера текущего месяца. 32 | 33 | ##### Формат вывода ##### 34 | Для каждой операции типа **DUMP** в отдельной строке выведите количество дел в соответствующий день, а затем их названия, разделяя их пробелом. Порядок вывода дел в рамках каждой операции значения не имеет. 35 | 36 | ##### Пример ##### 37 | ###### Ввод ###### 38 | ```objectivec 39 | 12 40 | ADD 5 Salary 41 | ADD 31 Walk 42 | ADD 30 WalkPreparations 43 | NEXT 44 | DUMP 5 45 | DUMP 28 46 | NEXT 47 | DUMP 31 48 | DUMP 30 49 | DUMP 28 50 | ADD 28 Payment 51 | DUMP 28 52 | ``` 53 | 54 | ###### Вывод ###### 55 | ```objectivec 56 | 1 Salary 57 | 2 WalkPreparations Walk 58 | 0 59 | 0 60 | 2 WalkPreparations Walk 61 | 3 WalkPreparations Walk Payment 62 | ``` 63 | -------------------------------------------------------------------------------- /week-04/12-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Работа с сервером времени #### 2 | 3 | Вам дана функция *string AskTimeServer()*, про которую известно следующее: 4 | 5 | * в процессе своей работы она обращается по сети к удалённому серверу, запрашивая текущее время; 6 | * если обращение к серверу прошло успешно, функция возвращает текущее время в виде строки; 7 | * если в процессе обращения к серверу возникла сетевая проблема, функция выбрасывает исключение *system_error*; 8 | * функция может выбрасывать другие исключения, чтобы сообщить о других проблемах. 9 | 10 | Используя функцию *AskTimeServer*, напишите класс *TimeServer* со следующим интерфейсом: 11 | ```objectivec 12 | class TimeServer { 13 | public: 14 | string GetCurrentTime(); 15 | private: 16 | string LastFetchedTime = "00:00:00"; 17 | }; 18 | ``` 19 | 20 | Метод *GetCurrentTime* должен вести себя так: 21 | 22 | * он должен вызвать функцию *AskTimeServer*, записать её результат в поле *LastFetchedTime* и вернуть значение этого поля; 23 | * если *AskTimeServer* выбросила исключение *system_error*, метод *GetCurrentTime* должен его поймать и вернуть текущее значение поля *LastFetchedTime*. Таким образом мы скрываем от пользователя сетевые проблемы, возвращая значение, которое было получено при последнем успешном обращении к серверу; 24 | * если *AskTimeServer* выбросила другое исключение, метод *GetCurrentTime* должен пробросить его дальше, потому что в рамках класса *TimeServer* мы не знаем, как обрабатывать проблемы, не связанные со сбоями сети. 25 | 26 | ##### Как выполнять задание ##### 27 | Вам дан файл, содержащий заготовку класса *TimeServer*. В нём вам надо реализовать метод *GetCurrentTime* так, как описано выше. Файл содержит пустую функцию *AskTimeServer*. Для тестирования своей реализации вы можете пробовать добавлять разные команды в её тело: 28 | 29 | * возврат строки; 30 | * выброс исключения *system_error* (класс *system_error* принимает в конструкторе параметр типа *error_code*, поэтому самый простой способ выбросить это исключение — *throw system_error(error_code());*, подробнее см. [http://www.cplusplus.com/reference/system_error/system_error](http://www.cplusplus.com/reference/system_error/system_error/)); 31 | * выброс других исключений. 32 | 33 | [time_server.cpp](https://github.com/avtomato/Basics-of-C-plus-plus-development-white-belt/blob/master/week-04/12-Programming-Assignment/Source/time_server.cpp) 34 | -------------------------------------------------------------------------------- /week-02/14-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Автобусные остановки — 2 #### 2 | 3 | В этой задаче вам нужно присваивать номера автобусным маршрутам. 4 | 5 | А именно, для каждого маршрута, заданного набором названий остановок, нужно либо выдать новый номер (первому маршруту — 1, второму — 2 и т. д.), либо вернуть номер существующего маршрута, которому соответствует такой набор остановок. 6 | 7 | Наборы остановок, полученные друг из друга перестановкой остановок, считаются различными (см. пример). 8 | 9 | ##### Указание ##### 10 | В C++ ключом словаря может быть не только число или строка, но и другой контейнер, например, *vector*. 11 | 12 | ##### Формат ввода ##### 13 | Сначала вводится количество запросов *Q*, затем *Q* описаний запросов. 14 | 15 | Каждый запрос представляет собой положительное количество остановок *N*, за которым следуют разделённые пробелом *N* различных названий остановок соответствующего маршрута. Названия остановок состоят лишь из латинских букв и символов подчёркивания. 16 | 17 | ##### Формат вывода ##### 18 | Выведите ответ на каждый запрос в отдельной строке. 19 | 20 | Если маршрут с данным набором остановок уже существует, в ответ на соответствующий запрос выведите **Already exists for *i***, где ***i*** — номер маршрута с таким набором остановок. В противном случае нужно выделить введённому набору остановок новый номер ***i*** и вывести его в формате **New bus *i***. 21 | 22 | ##### Пример ##### 23 | ###### Ввод ###### 24 | ```objectivec 25 | 4 26 | 2 Marushkino Kokoshkino 27 | 1 Kokoshkino 28 | 2 Marushkino Kokoshkino 29 | 2 Kokoshkino Marushkino 30 | ``` 31 | 32 | ###### Вывод ###### 33 | ```objectivec 34 | New bus 1 35 | New bus 2 36 | Already exists for 1 37 | New bus 3 38 | ``` 39 | 40 | ###### Замечание ###### 41 | Будьте внимательны при обновлении словаря: если одновременно в одном выражении вычислять размер словаря и добавлять в него новый элемент, результат может отличаться от ожидаемого на единицу. Чтобы этого избежать, используйте временную переменную. 42 | 43 | Например, вместо кода 44 | ```objectivec 45 | map m; 46 | // ... 47 | m["two"] = m.size(); 48 | // что нужно сделать раньше: вычислить size или добавить новый ключ? 49 | ``` 50 | 51 | стоит написать такой код: 52 | ```objectivec 53 | map m; 54 | // ... 55 | int new_value = m.size(); 56 | m["two"] = new_value; 57 | // теперь всё однозначно: нужен размер до добавления элемента 58 | ``` 59 | -------------------------------------------------------------------------------- /week-02/18-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Автобусные остановки — 3 #### 2 | 3 | В этой задаче вам нужно присваивать номера автобусным маршрутам. 4 | 5 | А именно, для каждого маршрута, заданного множеством названий остановок, нужно либо выдать новый номер (первому маршруту — 1, второму — 2 и т. д.), либо вернуть номер существующего маршрута, которому соответствует такое множество остановок. 6 | 7 | В отличие от задачи «Автобусные остановки — 2», наборы остановок, которые можно получить друг из друга перестановкой элементов или добавлением/удалением повторяющихся, следует считать одинаковыми. 8 | 9 | ##### Формат ввода ##### 10 | Сначала вводится количество запросов *Q*, затем *Q* описаний запросов. 11 | 12 | Каждый запрос представляет собой положительное количество остановок *N*, за которым следуют разделённые пробелом *N* названий остановок соответствующего маршрута (не обязательно различных). Названия остановок состоят лишь из латинских букв и символов подчёркивания. 13 | 14 | ##### Формат вывода ##### 15 | Выведите ответ на каждый запрос в отдельной строке. 16 | 17 | Если маршрут с данным набором остановок уже существует, в ответ на соответствующий запрос выведите **Already exists for *i***, где ***i*** — номер маршрута с таким набором остановок. В противном случае нужно выделить введённому набору остановок новый номер ***i*** и вывести его в формате **New bus *i***. 18 | 19 | ##### Пример ##### 20 | ###### Ввод ###### 21 | ```objectivec 22 | 5 23 | 2 Marushkino Kokoshkino 24 | 1 Kokoshkino 25 | 2 Marushkino Kokoshkino 26 | 2 Kokoshkino Marushkino 27 | 2 Kokoshkino Kokoshkino 28 | ``` 29 | 30 | ###### Вывод ###### 31 | ```objectivec 32 | New bus 1 33 | New bus 2 34 | Already exists for 1 35 | Already exists for 1 36 | Already exists for 2 37 | ``` 38 | 39 | ##### Замечание ##### 40 | Будьте внимательны при обновлении словаря: если одновременно в одном выражении вычислять размер словаря и добавлять в него новый элемент, результат может отличаться от ожидаемого на единицу. Чтобы этого избежать, используйте временную переменную. 41 | 42 | Например, вместо кода 43 | ```objectivec 44 | map m; 45 | // ... 46 | m["two"] = m.size(); 47 | // что нужно сделать раньше: вычислить size или добавить новый ключ? 48 | ``` 49 | стоит написать такой код: 50 | ```objectivec 51 | map m; 52 | // ... 53 | int new_value = m.size(); 54 | m["two"] = new_value; 55 | // теперь всё однозначно: нужен размер до добавления элемента 56 | ``` 57 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/rational_interface.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | class Rational { 7 | public: 8 | Rational() { 9 | // Реализуйте конструктор по умолчанию 10 | p = 0; 11 | q = 1; 12 | } 13 | 14 | Rational(int numerator, int denominator) { 15 | // Реализуйте конструктор 16 | int a = numerator, b = denominator, c = 0; 17 | while (b != 0) { 18 | c = a % b; 19 | a = b; 20 | b = c; 21 | } 22 | if (denominator / a < 0) { 23 | denominator = -denominator; 24 | numerator = -numerator; 25 | } 26 | p = numerator / a; 27 | q = denominator / a; 28 | } 29 | 30 | int Numerator() const { 31 | // Реализуйте этот метод 32 | return p; 33 | } 34 | 35 | int Denominator() const { 36 | // Реализуйте этот метод 37 | return q; 38 | } 39 | 40 | private: 41 | // Добавьте поля 42 | int p; 43 | int q; 44 | }; 45 | 46 | int main() { 47 | { 48 | const Rational r(3, 10); 49 | if (r.Numerator() != 3 || r.Denominator() != 10) { 50 | cout << "Rational(3, 10) != 3/10" << endl; 51 | return 1; 52 | } 53 | } 54 | 55 | { 56 | const Rational r(8, 12); 57 | if (r.Numerator() != 2 || r.Denominator() != 3) { 58 | cout << "Rational(8, 12) != 2/3" << endl; 59 | return 2; 60 | } 61 | } 62 | 63 | { 64 | const Rational r(-4, 6); 65 | if (r.Numerator() != -2 || r.Denominator() != 3) { 66 | cout << "Rational(-4, 6) != -2/3" << endl; 67 | return 3; 68 | } 69 | } 70 | 71 | { 72 | const Rational r(4, -6); 73 | if (r.Numerator() != -2 || r.Denominator() != 3) { 74 | cout << "Rational(4, -6) != -2/3" << endl; 75 | return 3; 76 | } 77 | } 78 | 79 | { 80 | const Rational r(0, 15); 81 | if (r.Numerator() != 0 || r.Denominator() != 1) { 82 | cout << "Rational(0, 15) != 0/1" << endl; 83 | return 4; 84 | } 85 | } 86 | 87 | { 88 | const Rational defaultConstructed; 89 | if (defaultConstructed.Numerator() != 0 || defaultConstructed.Denominator() != 1) { 90 | cout << "Rational() != 0/1" << endl; 91 | return 5; 92 | } 93 | } 94 | 95 | cout << "OK" << endl; 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /week-03/04-Programming-Assignment/names1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | class Person { 10 | public: 11 | void ChangeFirstName(int year, const string& first_name) { 12 | // добавить факт изменения имени на first_name в год year 13 | firstname[year] = first_name; 14 | } 15 | void ChangeLastName(int year, const string& last_name) { 16 | // добавить факт изменения фамилии на last_name в год year 17 | lastname[year] = last_name; 18 | } 19 | string GetFullName(int year) { 20 | // получить имя и фамилию по состоянию на конец года year 21 | string first_name = GetFirstName(year, firstname); 22 | string last_name = GetLastName(year, lastname); 23 | string full_name = first_name + " " + last_name; 24 | if (first_name.size() == 0 && last_name.size() == 0) { 25 | full_name = "Incognito"; 26 | return full_name; 27 | } else if (first_name.size() == 0) { 28 | full_name = last_name + " with unknown first name"; 29 | return full_name; 30 | } else if (last_name.size() == 0) { 31 | full_name = first_name + " with unknown last name"; 32 | return full_name; 33 | } 34 | return full_name; 35 | } 36 | private: 37 | // приватные поля 38 | string GetFirstName(int year, map& firstname) { 39 | while (firstname.count(year) == 0 && year > 0) { 40 | --year; 41 | } 42 | string first = firstname[year]; 43 | return first; 44 | } 45 | string GetLastName(int year, map& lastname) { 46 | while (lastname.count(year) == 0 && year > 0) { 47 | --year; 48 | } 49 | string last = lastname[year]; 50 | return last; 51 | } 52 | 53 | map firstname; 54 | map lastname; 55 | }; 56 | 57 | int main() { 58 | Person person; 59 | 60 | person.ChangeFirstName(1965, "Polina"); 61 | person.ChangeLastName(1967, "Sergeeva"); 62 | for (int year : {1900, 1965, 1990}) { 63 | cout << person.GetFullName(year) << endl; 64 | } 65 | 66 | person.ChangeFirstName(1970, "Appolinaria"); 67 | for (int year : {1969, 1970}) { 68 | cout << person.GetFullName(year) << endl; 69 | } 70 | 71 | person.ChangeLastName(1968, "Volkova"); 72 | for (int year : {1969, 1970}) { 73 | cout << person.GetFullName(year) << endl; 74 | } 75 | 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /week-04/02-Practice-Programming-Assignment/invertible_function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | struct Image { 10 | double quality; 11 | double freshness; 12 | double rating; 13 | }; 14 | 15 | struct Params { 16 | double a; 17 | double b; 18 | double c; 19 | }; 20 | 21 | class FunctionsPart{ 22 | public: 23 | FunctionsPart(char new_operation, double new_value) { 24 | operation = new_operation; 25 | value = new_value; 26 | } 27 | 28 | double Apply(double source_value) const { 29 | if (operation == '+') { 30 | return source_value + value; 31 | } else { 32 | return source_value - value; 33 | } 34 | } 35 | 36 | void Invert() { 37 | if (operation == '+') { 38 | operation = '-'; 39 | } else { 40 | operation = '+'; 41 | } 42 | } 43 | 44 | private: 45 | char operation; 46 | double value; 47 | }; 48 | 49 | class Function { 50 | public: 51 | void AddPart(char operation, double value) { 52 | parts.push_back({operation, value}); 53 | } 54 | double Apply(double value) const { 55 | for (const FunctionsPart& part : parts) { 56 | value = part.Apply(value); 57 | } 58 | return value; 59 | } 60 | void Invert() { 61 | for (FunctionsPart& part : parts) { 62 | part.Invert(); 63 | } 64 | reverse(begin(parts), end(parts)); 65 | } 66 | 67 | private: 68 | vector parts; 69 | }; 70 | 71 | Function MakeWeightFunction(const Params& params, 72 | const Image& image) { 73 | Function function; 74 | function.AddPart('-', image.freshness * params.a + params.b); 75 | function.AddPart('+', image.rating * params.c); 76 | return function; 77 | } 78 | 79 | double ComputeImageWeight(const Params& params, const Image& image) { 80 | Function function = MakeWeightFunction(params, image); 81 | return function.Apply(image.quality); 82 | } 83 | 84 | double ComputeQualityByWeight(const Params& params, 85 | const Image& image, 86 | double weight) { 87 | Function function = MakeWeightFunction(params, image); 88 | function.Invert(); 89 | return function.Apply(weight); 90 | } 91 | 92 | int main() { 93 | Image image = {10, 2, 6}; 94 | Params params = {4, 2, 6}; 95 | cout << ComputeImageWeight(params, image) << endl; 96 | cout << ComputeQualityByWeight(params, image, 46) << endl; 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /week-03/04-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Имена и фамилии — 1 #### 2 | 3 | Реализуйте класс для человека, поддерживающий историю изменений человеком своих фамилии и имени. 4 | 5 | ```objectivec 6 | class Person { 7 | public: 8 | void ChangeFirstName(int year, const string& first_name) { 9 | // добавить факт изменения имени на first_name в год year 10 | } 11 | void ChangeLastName(int year, const string& last_name) { 12 | // добавить факт изменения фамилии на last_name в год year 13 | } 14 | string GetFullName(int year) { 15 | // получить имя и фамилию по состоянию на конец года year 16 | } 17 | private: 18 | // приватные поля 19 | }; 20 | ``` 21 | Считайте, что в каждый год может произойти не более одного изменения фамилии и не более одного изменения имени. При этом с течением времени могут открываться всё новые факты из прошлого человека, поэтому года́ в последовательных вызовах методов *ChangeLastName* и *ChangeFirstName* не обязаны возрастать. 22 | 23 | Гарантируется, что все имена и фамилии непусты. 24 | 25 | Строка, возвращаемая методом *GetFullName*, должна содержать разделённые одним пробелом имя и фамилию человека по состоянию на конец данного года. 26 | 27 | * Если к данному году не случилось ни одного изменения фамилии и имени, верните строку **"Incognito"**. 28 | * Если к данному году случилось изменение фамилии, но не было ни одного изменения имени, верните **"last_name with unknown first name"**. 29 | * Если к данному году случилось изменение имени, но не было ни одного изменения фамилии, верните **"first_name with unknown last name"**. 30 | 31 | ##### Пример ##### 32 | ###### Код ###### 33 | ```objectivec 34 | int main() { 35 | Person person; 36 | 37 | person.ChangeFirstName(1965, "Polina"); 38 | person.ChangeLastName(1967, "Sergeeva"); 39 | for (int year : {1900, 1965, 1990}) { 40 | cout << person.GetFullName(year) << endl; 41 | } 42 | 43 | person.ChangeFirstName(1970, "Appolinaria"); 44 | for (int year : {1969, 1970}) { 45 | cout << person.GetFullName(year) << endl; 46 | } 47 | 48 | person.ChangeLastName(1968, "Volkova"); 49 | for (int year : {1969, 1970}) { 50 | cout << person.GetFullName(year) << endl; 51 | } 52 | 53 | return 0; 54 | } 55 | ``` 56 | 57 | ###### Вывод ###### 58 | ```objectivec 59 | Incognito 60 | Polina with unknown last name 61 | Polina Sergeeva 62 | Polina Sergeeva 63 | Appolinaria Sergeeva 64 | Polina Volkova 65 | Appolinaria Volkova 66 | ``` 67 | 68 | 69 | ##### Пояснение ##### 70 | 71 | В этой задаче вам надо прислать файл с реализацией класса *Person*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 72 | -------------------------------------------------------------------------------- /week-03/07-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | vector FindNamesHistory(const map& names_by_year, 6 | int year) { 7 | vector names; 8 | for (const auto& item : names_by_year) { 9 | if (item.first <= year && (names.empty() || names.back() != item.second)) { 10 | names.push_back(item.second); 11 | } 12 | } 13 | return names; 14 | } 15 | 16 | string BuildJoinedName(vector names) { 17 | reverse(begin(names), end(names)); 18 | string joined_name = names[0]; 19 | for (int i = 1; i < names.size(); ++i) { 20 | if (i == 1) { 21 | joined_name += " ("; 22 | } else { 23 | joined_name += ", "; 24 | } 25 | joined_name += names[i]; 26 | } 27 | if (names.size() > 1) { 28 | joined_name += ")"; 29 | } 30 | return joined_name; 31 | } 32 | 33 | class Person { 34 | public: 35 | // конструктор 36 | Person(const string& first_name, const string& last_name, 37 | int new_birth_year) { 38 | birth_year = new_birth_year; 39 | first_names[birth_year] = first_name; 40 | last_names[birth_year] = last_name; 41 | } 42 | void ChangeFirstName(int year, const string& first_name) { 43 | // игнорируем запись, если год меньше года рождения 44 | if (year >= birth_year) { 45 | first_names[year] = first_name; 46 | } 47 | } 48 | void ChangeLastName(int year, const string& last_name) { 49 | if (year >= birth_year) { 50 | last_names[year] = last_name; 51 | } 52 | } 53 | string GetFullName(int year) const { 54 | // обрабатываем случай, когда год меньше года рождения 55 | if (year < birth_year) { 56 | return "No person"; 57 | } 58 | const vector first_names = FindFirstNamesHistory(year); 59 | const vector last_names = FindLastNamesHistory(year); 60 | // объединяем имя и фамилию через пробел 61 | return first_names.back() + " " + last_names.back(); 62 | } 63 | string GetFullNameWithHistory(int year) const { 64 | if (year < birth_year) { 65 | return "No person"; 66 | } 67 | const string first_name = BuildJoinedName(FindFirstNamesHistory(year)); 68 | const string last_name = BuildJoinedName(FindLastNamesHistory(year)); 69 | return first_name + " " + last_name; 70 | } 71 | private: 72 | vector FindFirstNamesHistory(int year) const { 73 | return FindNamesHistory(first_names, year); 74 | } 75 | vector FindLastNamesHistory(int year) const { 76 | return FindNamesHistory(last_names, year); 77 | } 78 | 79 | int birth_year; 80 | map first_names; 81 | map last_names; 82 | }; 83 | -------------------------------------------------------------------------------- /week-02/12-Practice-Programming-Assignment/countries.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | void PrintMap(const map& m) { 9 | for (const auto& item : m) { 10 | cout << item.first << "/" << item.second << " "; 11 | } 12 | cout << endl; 13 | } 14 | 15 | int main() { 16 | int q; 17 | cin >> q; 18 | map countries; 19 | 20 | for (int i = 0; i < q; ++i) { 21 | string operation_code; 22 | cin >> operation_code; 23 | if (operation_code == "CHANGE_CAPITAL") { 24 | string country, new_capital; 25 | cin >> country >> new_capital; 26 | if (countries[country] == "") { 27 | cout << "Introduce new country " << country << " with capital " << new_capital << endl; 28 | countries.erase(country); 29 | } else if (countries[country] == new_capital) { 30 | cout << "Country " << country << " hasn't changed its capital" << endl; 31 | } else if (countries[country] != new_capital) { 32 | cout << "Country " << country << " has changed its capital from " << countries[country] << " to " << new_capital << endl; 33 | } 34 | countries[country] = new_capital; 35 | } else if (operation_code == "RENAME") { 36 | string old_country_name, new_country_name; 37 | cin >> old_country_name >> new_country_name; 38 | if (new_country_name == old_country_name) { 39 | cout << "Incorrect rename, skip" << endl; 40 | } else if (countries.count(new_country_name)) { 41 | cout << "Incorrect rename, skip" << endl; 42 | } else if (countries[old_country_name] == "") { 43 | cout << "Incorrect rename, skip" << endl; 44 | countries.erase(old_country_name); 45 | } else { 46 | cout << "Country " << old_country_name << " with capital " << countries[old_country_name] << " has been renamed to " << new_country_name << endl; 47 | countries[new_country_name] = countries[old_country_name]; 48 | countries.erase(old_country_name); 49 | } 50 | } else if (operation_code == "ABOUT") { 51 | string country; 52 | cin >> country; 53 | if (countries[country] == "") { 54 | cout << "Country " << country << " doesn't exist" << endl; 55 | countries.erase(country); 56 | } else { 57 | cout << "Country " << country << " has capital " << countries[country] << endl; 58 | } 59 | } else if (operation_code == "DUMP") { 60 | if (countries.size() == 0) { 61 | cout << "There are no countries in the world" << endl; 62 | } else { 63 | PrintMap(countries); 64 | } 65 | } 66 | } 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /week-04/03-Programming-Assignment/invertible_function_with_mult.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | struct Image { 10 | double quality; 11 | double freshness; 12 | double rating; 13 | }; 14 | 15 | struct Params { 16 | double a; 17 | double b; 18 | double c; 19 | }; 20 | 21 | class FunctionsPart{ 22 | public: 23 | FunctionsPart(char new_operation, double new_value) { 24 | operation = new_operation; 25 | value = new_value; 26 | } 27 | 28 | double Apply(double source_value) const { 29 | if (operation == '+') { 30 | return source_value + value; 31 | } else if (operation == '-') { 32 | return source_value - value; 33 | } else if (operation == '*') { 34 | return source_value * value; 35 | } else { 36 | return source_value / value; 37 | } 38 | } 39 | 40 | void Invert() { 41 | if (operation == '+') { 42 | operation = '-'; 43 | } else if (operation == '-') { 44 | operation = '+'; 45 | } else if (operation == '*') { 46 | operation = '/'; 47 | } else { 48 | operation = '*'; 49 | } 50 | } 51 | 52 | private: 53 | char operation; 54 | double value; 55 | }; 56 | 57 | class Function { 58 | public: 59 | void AddPart(char operation, double value) { 60 | parts.push_back({operation, value}); 61 | } 62 | double Apply(double value) const { 63 | for (const FunctionsPart& part : parts) { 64 | value = part.Apply(value); 65 | } 66 | return value; 67 | } 68 | void Invert() { 69 | for (FunctionsPart& part : parts) { 70 | part.Invert(); 71 | } 72 | reverse(begin(parts), end(parts)); 73 | } 74 | 75 | private: 76 | vector parts; 77 | }; 78 | 79 | Function MakeWeightFunction(const Params& params, 80 | const Image& image) { 81 | Function function; 82 | function.AddPart('*', params.a); 83 | function.AddPart('-', image.freshness * params.b); 84 | function.AddPart('+', image.rating * params.c); 85 | return function; 86 | } 87 | 88 | double ComputeImageWeight(const Params& params, const Image& image) { 89 | Function function = MakeWeightFunction(params, image); 90 | return function.Apply(image.quality); 91 | } 92 | 93 | double ComputeQualityByWeight(const Params& params, 94 | const Image& image, 95 | double weight) { 96 | Function function = MakeWeightFunction(params, image); 97 | function.Invert(); 98 | return function.Apply(weight); 99 | } 100 | 101 | int main() { 102 | Image image = {10, 2, 6}; 103 | Params params = {4, 2, 6}; 104 | cout << ComputeImageWeight(params, image) << endl; 105 | cout << ComputeQualityByWeight(params, image, 52) << endl; 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/rational_eq_add_sub.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | class Rational { 7 | public: 8 | Rational() { 9 | // Реализуйте конструктор по умолчанию 10 | p = 0; 11 | q = 1; 12 | } 13 | 14 | Rational(int numerator, int denominator) { 15 | // Реализуйте конструктор 16 | int a = numerator, b = denominator, c = 0; 17 | while (b != 0) { 18 | c = a % b; 19 | a = b; 20 | b = c; 21 | } 22 | p = numerator / a; 23 | q = denominator / a; 24 | } 25 | 26 | int Numerator() const { 27 | // Реализуйте этот метод 28 | return p; 29 | } 30 | 31 | int Denominator() const { 32 | // Реализуйте этот метод 33 | return q; 34 | } 35 | 36 | private: 37 | // Добавьте поля 38 | int p; 39 | int q; 40 | }; 41 | 42 | bool operator == (const Rational& lhs, const Rational& rhs) { 43 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 44 | while (b != 0) { 45 | c = a % b; 46 | a = b; 47 | b = c; 48 | } 49 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 50 | int l = n / lhs.Denominator(); 51 | int r = n / rhs.Denominator(); 52 | return (lhs.Numerator() * l) == (rhs.Numerator() *r); 53 | } 54 | 55 | Rational operator + (const Rational& lhs, const Rational& rhs) { 56 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 57 | while (b != 0) { 58 | c = a % b; 59 | a = b; 60 | b = c; 61 | } 62 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 63 | int l = n / lhs.Denominator(); 64 | int r = n / rhs.Denominator(); 65 | return Rational((lhs.Numerator() * l) + (rhs.Numerator() *r), n); 66 | } 67 | 68 | Rational operator - (const Rational& lhs, const Rational& rhs) { 69 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 70 | while (b != 0) { 71 | c = a % b; 72 | a = b; 73 | b = c; 74 | } 75 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 76 | int l = n / lhs.Denominator(); 77 | int r = n / rhs.Denominator(); 78 | return Rational((lhs.Numerator() * l) - (rhs.Numerator() *r), n); 79 | } 80 | 81 | int main() { 82 | { 83 | Rational r1(4, 6); 84 | Rational r2(2, 3); 85 | bool equal = r1 == r2; 86 | if (!equal) { 87 | cout << "4/6 != 2/3" << endl; 88 | return 1; 89 | } 90 | } 91 | 92 | { 93 | Rational a(2, 3); 94 | Rational b(4, 3); 95 | Rational c = a + b; 96 | bool equal = c == Rational(2, 1); 97 | if (!equal) { 98 | cout << "2/3 + 4/3 != 2" << endl; 99 | return 2; 100 | } 101 | } 102 | 103 | { 104 | Rational a(5, 7); 105 | Rational b(2, 9); 106 | Rational c = a - b; 107 | bool equal = c == Rational(31, 63); 108 | if (!equal) { 109 | cout << "5/7 - 2/9 != 31/63" << endl; 110 | return 3; 111 | } 112 | } 113 | 114 | cout << "OK" << endl; 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/rational_mult_div.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | class Rational { 7 | public: 8 | Rational() { 9 | // Реализуйте конструктор по умолчанию 10 | p = 0; 11 | q = 1; 12 | } 13 | 14 | Rational(int numerator, int denominator) { 15 | // Реализуйте конструктор 16 | int a = numerator, b = denominator, c = 0; 17 | while (b != 0) { 18 | c = a % b; 19 | a = b; 20 | b = c; 21 | } 22 | p = numerator / a; 23 | q = denominator / a; 24 | } 25 | 26 | int Numerator() const { 27 | // Реализуйте этот метод 28 | return p; 29 | } 30 | 31 | int Denominator() const { 32 | // Реализуйте этот метод 33 | return q; 34 | } 35 | 36 | private: 37 | // Добавьте поля 38 | int p; 39 | int q; 40 | }; 41 | 42 | bool operator == (const Rational& lhs, const Rational& rhs) { 43 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 44 | while (b != 0) { 45 | c = a % b; 46 | a = b; 47 | b = c; 48 | } 49 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 50 | int l = n / lhs.Denominator(); 51 | int r = n / rhs.Denominator(); 52 | return (lhs.Numerator() * l) == (rhs.Numerator() *r); 53 | } 54 | 55 | Rational operator + (const Rational& lhs, const Rational& rhs) { 56 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 57 | while (b != 0) { 58 | c = a % b; 59 | a = b; 60 | b = c; 61 | } 62 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 63 | int l = n / lhs.Denominator(); 64 | int r = n / rhs.Denominator(); 65 | return Rational((lhs.Numerator() * l) + (rhs.Numerator() *r), n); 66 | } 67 | 68 | Rational operator - (const Rational& lhs, const Rational& rhs) { 69 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 70 | while (b != 0) { 71 | c = a % b; 72 | a = b; 73 | b = c; 74 | } 75 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 76 | int l = n / lhs.Denominator(); 77 | int r = n / rhs.Denominator(); 78 | return Rational((lhs.Numerator() * l) - (rhs.Numerator() *r), n); 79 | } 80 | 81 | Rational operator * (const Rational& lhs, const Rational& rhs) { 82 | return Rational(lhs.Numerator() * rhs.Numerator(), lhs.Denominator() * rhs.Denominator()); 83 | } 84 | 85 | Rational operator / (const Rational& lhs, const Rational& rhs) { 86 | return Rational(lhs.Numerator() * rhs.Denominator(), lhs.Denominator() * rhs.Numerator()); 87 | } 88 | 89 | int main() { 90 | { 91 | Rational a(2, 3); 92 | Rational b(4, 3); 93 | Rational c = a * b; 94 | bool equal = c == Rational(8, 9); 95 | if (!equal) { 96 | cout << "2/3 * 4/3 != 8/9" << endl; 97 | return 1; 98 | } 99 | } 100 | 101 | { 102 | Rational a(5, 4); 103 | Rational b(15, 8); 104 | Rational c = a / b; 105 | bool equal = c == Rational(2, 3); 106 | if (!equal) { 107 | cout << "5/4 / 15/8 != 2/3" << endl; 108 | return 2; 109 | } 110 | } 111 | 112 | cout << "OK" << endl; 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /week-02/10-Programming-Assignment/Solution/MonthlyBusiness.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // глобальные (доступные во всей программе) константы 8 | // часто принято называть ЗАГЛАВНЫМИ_БУКВАМИ 9 | const vector MONTH_LENGTHS = 10 | {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 11 | const int MONTH_COUNT = MONTH_LENGTHS.size(); 12 | 13 | int main() { 14 | int q; 15 | cin >> q; 16 | 17 | // номер текущего месяца (от 0 до 11) 18 | int month = 0; 19 | 20 | // внешний вектор должен иметь длину, равную количеству дней в первом месяце; 21 | // все внутренние векторы по умолчанию пусты, потому что дел изначально нет 22 | vector> days_concerns(MONTH_LENGTHS[month]); 23 | 24 | for (int i = 0; i < q; ++i) { 25 | string operation_code; 26 | cin >> operation_code; 27 | 28 | if (operation_code == "ADD") { 29 | 30 | int day; 31 | string concern; 32 | cin >> day >> concern; 33 | --day; // элементы вектора нумеруются с нуля 34 | days_concerns[day].push_back(concern); 35 | 36 | } else if (operation_code == "NEXT") { 37 | 38 | // перед переходом к следующему месяцу запомним длину предыдущего 39 | // обьявляем эту переменную константной, потому что менять её не планируем 40 | const int old_month_length = MONTH_LENGTHS[month]; 41 | 42 | // номер месяца должен увеличиться на 1, но после декабря идёт январь: 43 | // например, (5 + 1) % 12 = 6, но (11 + 1) % 12 = 0 44 | month = (month + 1) % MONTH_COUNT; 45 | 46 | const int new_month_length = MONTH_LENGTHS[month]; 47 | 48 | // если новый месяц больше предыдущего, достаточно сделать resize; 49 | // иначе перед resize надо переместить дела с «лишних» последних дней 50 | if (new_month_length < old_month_length) { 51 | 52 | // далее понадобится добавлять новые дела в последний день нового месяца 53 | // чтобы не писать несколько раз days_concerns[new_month_length - 1], 54 | // создадим ссылку с более коротким названием для этого вектора 55 | vector& last_day_concerns = days_concerns[new_month_length - 1]; 56 | 57 | // перебираем все «лишние» дни в конце месяца 58 | for (int day = new_month_length; day < old_month_length; ++day) { 59 | // копируем вектор days_concerns[day] 60 | // в конец вектора last_day_concerns 61 | last_day_concerns.insert( 62 | end(last_day_concerns), 63 | begin(days_concerns[day]), end(days_concerns[day])); 64 | } 65 | } 66 | days_concerns.resize(new_month_length); 67 | 68 | } else if (operation_code == "DUMP") { 69 | 70 | int day; 71 | cin >> day; 72 | --day; 73 | 74 | // выводим список дел в конкретный день в нужном формате 75 | cout << days_concerns[day].size() << " "; 76 | for (const string& concern : days_concerns[day]) { 77 | cout << concern << " "; 78 | } 79 | cout << endl; 80 | 81 | } 82 | } 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // один из способов вычисления наибольшего общего делителя (НОД) — рекурсивный: 6 | // вместо цикла функция будет вызывать себя же, но с другими аргументами 7 | int GreatestCommonDivisor(int a, int b) { 8 | if (b == 0) { 9 | return a; 10 | } else { 11 | return GreatestCommonDivisor(b, a % b); 12 | } 13 | } 14 | 15 | class Rational { 16 | public: 17 | Rational() { // дробь по умолчанию — 0/1 18 | numerator = 0; 19 | denominator = 1; 20 | } 21 | Rational(int new_numerator, int new_denominator) { 22 | const int gcd = GreatestCommonDivisor(new_numerator, new_denominator); 23 | // сократим дробь, разделив числитель и знаменатель на их НОД 24 | numerator = new_numerator / gcd; 25 | denominator = new_denominator / gcd; 26 | // знаменатель должен быть положительным 27 | if (denominator < 0) { 28 | denominator = -denominator; 29 | numerator = -numerator; 30 | } 31 | } 32 | 33 | int Numerator() const { 34 | return numerator; 35 | } 36 | 37 | int Denominator() const { 38 | return denominator; 39 | } 40 | 41 | private: 42 | int numerator; 43 | int denominator; 44 | }; 45 | 46 | // поскольку дроби сокращены, достаточно сравнить числители и знаменатели 47 | bool operator == (const Rational& lhs, const Rational& rhs) { 48 | return lhs.Numerator() == rhs.Numerator() && 49 | lhs.Denominator() == rhs.Denominator(); 50 | } 51 | 52 | // используем обычную формулу сложения дробей, основанную на приведении слагаемых к общему знаменателю 53 | Rational operator + (const Rational& lhs, const Rational& rhs) { 54 | return { 55 | lhs.Numerator() * rhs.Denominator() + rhs.Numerator() * lhs.Denominator(), 56 | lhs.Denominator() * rhs.Denominator() 57 | }; 58 | } 59 | 60 | // вычитание реализуем аналогично сложению 61 | // дублирования кода можно было избежать, определив для класса Rational операцию унарного минуса: тогда разность lhs и rhs можно было бы вычислить как lhs + (-rhs) 62 | Rational operator - (const Rational& lhs, const Rational& rhs) { 63 | return { 64 | lhs.Numerator() * rhs.Denominator() - rhs.Numerator() * lhs.Denominator(), 65 | lhs.Denominator() * rhs.Denominator() 66 | }; 67 | } 68 | 69 | Rational operator * (const Rational& lhs, const Rational& rhs) { 70 | return { 71 | lhs.Numerator() * rhs.Numerator(), 72 | lhs.Denominator() * rhs.Denominator() 73 | }; 74 | } 75 | 76 | // деление равносильно умножению на обратную («перевёрнутую») дробь 77 | Rational operator / (const Rational& lhs, const Rational& rhs) { 78 | return lhs * Rational(rhs.Denominator(), rhs.Numerator()); 79 | } 80 | 81 | istream& operator >> (istream& is, Rational& r) { 82 | int n, d; 83 | char c; 84 | is >> n >> c >> d; 85 | if (is && c == '/') { 86 | r = Rational(n, d); 87 | } 88 | return is; 89 | } 90 | 91 | ostream& operator << (ostream& os, const Rational& r) { 92 | return os << r.Numerator() << '/' << r.Denominator(); 93 | } 94 | 95 | // чтобы сравнить lhs с rhs, сравним их разность с нулём, что равносильно сравнению с нулём числителя 96 | bool operator < (const Rational& lhs, const Rational& rhs) { 97 | return (lhs - rhs).Numerator() < 0; 98 | } 99 | -------------------------------------------------------------------------------- /week-02/13-Programming-Assignment/buses1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | 10 | int main() { 11 | int q; 12 | cin >> q; 13 | map> buses; 14 | map> stops; 15 | 16 | for (int i = 0; i < q; ++i) { 17 | string operation_code; 18 | cin >> operation_code; 19 | if (operation_code == "NEW_BUS") { 20 | string bus; 21 | int stop_count; 22 | cin >> bus; 23 | cin >> stop_count; 24 | vector v(stop_count); 25 | for (string& s : v) { 26 | cin >> s; 27 | vector v2; 28 | v2.push_back(bus); 29 | if (stops.count(s)) { 30 | stops[s].insert(end(stops[s]), begin(v2), end(v2)); 31 | } else { 32 | stops[s] = v2; 33 | } 34 | } 35 | buses[bus] = v; 36 | } else if (operation_code == "BUSES_FOR_STOP") { 37 | string stop; 38 | cin >> stop; 39 | if (stops[stop].size() == 0) { 40 | cout << "No stop" << endl; 41 | stops.erase(stop); 42 | } else { 43 | for (const auto& item : stops) { 44 | if (item.first == stop) { 45 | for (string w : item.second) { 46 | cout << w << " "; 47 | } 48 | cout << endl; 49 | } 50 | } 51 | } 52 | } else if (operation_code == "STOPS_FOR_BUS") { 53 | string bus; 54 | cin >> bus; 55 | if (buses.count(bus) > 0) { 56 | for (const auto& item : buses) { 57 | if (item.first == bus) { 58 | for (string w : item.second) { 59 | cout << "Stop " << w << ": "; 60 | for (const auto& item2 : stops) { 61 | if (item2.first == w) { 62 | if (item2.second.size() == 1) { 63 | cout << "no interchange" << endl; 64 | } else { 65 | for (string w2 : item2.second) { 66 | if (w2 != bus) { 67 | cout << w2 << " "; 68 | } 69 | } 70 | cout << endl; 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } 77 | } else { 78 | cout << "No bus" << endl; 79 | } 80 | } else if (operation_code == "ALL_BUSES") { 81 | if (buses.size() == 0) { 82 | cout << "No buses" << endl; 83 | } else { 84 | for (const auto& item : buses) { 85 | cout << "Bus " << item.first << ": "; 86 | for (string w : item.second) { 87 | cout << w << " "; 88 | } 89 | cout << endl; 90 | } 91 | cout << endl; 92 | } 93 | } 94 | } 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /week-02/13-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Автобусные остановки — 1 #### 2 | 3 | 4 | Реализуйте систему хранения автобусных маршрутов. Вам нужно обрабатывать следующие запросы: 5 | 6 | * **NEW_BUS *bus stop_count stop1 stop2 ...*** — добавить маршрут автобуса с названием ***bus*** и ***stop_count*** остановками с названиями ***stop1, stop2, ...*** 7 | * **BUSES_FOR_STOP *stop*** — вывести названия всех маршрутов автобуса, проходящих через остановку ***stop***. 8 | * **STOPS_FOR_BUS *bus*** — вывести названия всех остановок маршрута ***bus*** со списком автобусов, на которые можно пересесть на каждой из остановок. 9 | * **ALL_BUSES** — вывести список всех маршрутов с остановками. 10 | 11 | ##### Формат ввода ##### 12 | В первой строке ввода содержится количество запросов *Q*, затем в *Q* строках следуют описания запросов. 13 | 14 | Гарантируется, что все названия маршрутов и остановок состоят лишь из латинских букв, цифр и знаков подчёркивания. 15 | 16 | Для каждого запроса **NEW_BUS *bus stop_count stop1 stop2 ...*** гарантируется, что маршрут ***bus*** отсутствует, количество остановок больше 0, а после числа ***stop_count*** следует именно такое количество названий остановок, причём все названия в каждом списке различны. 17 | 18 | ##### Формат вывода ##### 19 | Для каждого запроса, кроме **NEW_BUS**, выведите соответствующий ответ на него: 20 | 21 | * На запрос **BUSES_FOR_STOP *stop*** выведите через пробел список автобусов, проезжающих через эту остановку, в том порядке, в котором они создавались командами **NEW_BUS**. Если остановка ***stop*** не существует, выведите **No stop**. 22 | * На запрос **STOPS_FOR_BUS *bus*** выведите описания остановок маршрута ***bus*** в отдельных строках в том порядке, в котором они были заданы в соответствующей команде **NEW_BUS**. Описание каждой остановки ***stop*** должно иметь вид **Stop *stop: bus1 bus2 ...***, где ***bus1 bus2 ...*** — список автобусов, проезжающих через остановку ***stop***, в порядке, в котором они создавались командами **NEW_BUS**, за исключением исходного маршрута ***bus***. Если через остановку ***stop*** не проезжает ни один автобус, кроме ***bus***, вместо списка автобусов для неё выведите **no interchange**. Если маршрут ***bus*** не существует, выведите **No bus**. 23 | * На запрос **ALL_BUSES** выведите описания всех автобусов в алфавитном порядке. Описание каждого маршрута ***bus*** должно иметь вид **Bus *bus: stop1 stop2 ...***, где ***stop1 stop2 ...*** — список остановок автобуса ***bus*** в порядке, в котором они были заданы в соответствующей команде **NEW_BUS**. Если автобусы отсутствуют, выведите **No buses**. 24 | 25 | ##### Предупреждение ##### 26 | Условие задачи выше содержит много важных деталей. Если вы не уверены в том, что не упустили ни одной, перечитайте условие ещё раз. 27 | 28 | ##### Пример ##### 29 | ###### Ввод ###### 30 | ```commandline 31 | 10 32 | ALL_BUSES 33 | BUSES_FOR_STOP Marushkino 34 | STOPS_FOR_BUS 32K 35 | NEW_BUS 32 3 Tolstopaltsevo Marushkino Vnukovo 36 | NEW_BUS 32K 6 Tolstopaltsevo Marushkino Vnukovo Peredelkino Solntsevo Skolkovo 37 | BUSES_FOR_STOP Vnukovo 38 | NEW_BUS 950 6 Kokoshkino Marushkino Vnukovo Peredelkino Solntsevo Troparyovo 39 | NEW_BUS 272 4 Vnukovo Moskovsky Rumyantsevo Troparyovo 40 | STOPS_FOR_BUS 272 41 | ALL_BUSES 42 | ``` 43 | ###### Вывод ###### 44 | ```commandline 45 | No buses 46 | No stop 47 | No bus 48 | 32 32K 49 | Stop Vnukovo: 32 32K 950 50 | Stop Moskovsky: no interchange 51 | Stop Rumyantsevo: no interchange 52 | Stop Troparyovo: 950 53 | Bus 272: Vnukovo Moskovsky Rumyantsevo Troparyovo 54 | Bus 32: Tolstopaltsevo Marushkino Vnukovo 55 | Bus 32K: Tolstopaltsevo Marushkino Vnukovo Peredelkino Solntsevo Skolkovo 56 | Bus 950: Kokoshkino Marushkino Vnukovo Peredelkino Solntsevo Troparyovo 57 | ``` 58 | -------------------------------------------------------------------------------- /week-03/05-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Имена и фамилии — 2 #### 2 | 3 | Дополните класс из предыдущей задачи «Имена и фамилии — 1» методом *GetFullNameWithHistory*: 4 | 5 | ```objectivec 6 | class Person { 7 | public: 8 | void ChangeFirstName(int year, const string& first_name) { 9 | // добавить факт изменения имени на first_name в год year 10 | } 11 | void ChangeLastName(int year, const string& last_name) { 12 | // добавить факт изменения фамилии на last_name в год year 13 | } 14 | string GetFullName(int year) { 15 | // получить имя и фамилию по состоянию на конец года year 16 | } 17 | string GetFullNameWithHistory(int year) { 18 | // получить все имена и фамилии по состоянию на конец года year 19 | } 20 | private: 21 | // приватные поля 22 | }; 23 | ``` 24 | 25 | В отличие от метода *GetFullName*, метод *GetFullNameWithHistory* должен вернуть не только последние имя и фамилию к концу данного года, но ещё и все предыдущие имена и фамилии в обратном хронологическом порядке. Если текущие факты говорят о том, что человек два раза подряд изменил фамилию или имя на одно и то же, второе изменение при формировании истории нужно игнорировать. 26 | 27 | Для лучшего понимания формата см. примеры. 28 | 29 | ##### Пример 1 ##### 30 | ###### Код ###### 31 | ```objectivec 32 | int main() { 33 | Person person; 34 | 35 | person.ChangeFirstName(1900, "Eugene"); 36 | person.ChangeLastName(1900, "Sokolov"); 37 | person.ChangeLastName(1910, "Sokolov"); 38 | person.ChangeFirstName(1920, "Evgeny"); 39 | person.ChangeLastName(1930, "Sokolov"); 40 | cout << person.GetFullNameWithHistory(1940) << endl; 41 | 42 | return 0; 43 | } 44 | ``` 45 | 46 | ###### Вывод ###### 47 | ```objectivec 48 | Evgeny (Eugene) Sokolov 49 | ``` 50 | 51 | ##### Пример 2 ##### 52 | ###### Код ###### 53 | ```objectivec 54 | int main() { 55 | Person person; 56 | 57 | person.ChangeFirstName(1965, "Polina"); 58 | person.ChangeLastName(1967, "Sergeeva"); 59 | for (int year : {1900, 1965, 1990}) { 60 | cout << person.GetFullNameWithHistory(year) << endl; 61 | } 62 | 63 | person.ChangeFirstName(1970, "Appolinaria"); 64 | for (int year : {1969, 1970}) { 65 | cout << person.GetFullNameWithHistory(year) << endl; 66 | } 67 | 68 | person.ChangeLastName(1968, "Volkova"); 69 | for (int year : {1969, 1970}) { 70 | cout << person.GetFullNameWithHistory(year) << endl; 71 | } 72 | 73 | person.ChangeFirstName(1990, "Polina"); 74 | person.ChangeLastName(1990, "Volkova-Sergeeva"); 75 | cout << person.GetFullNameWithHistory(1990) << endl; 76 | 77 | person.ChangeFirstName(1966, "Pauline"); 78 | cout << person.GetFullNameWithHistory(1966) << endl; 79 | 80 | person.ChangeLastName(1960, "Sergeeva"); 81 | for (int year : {1960, 1967}) { 82 | cout << person.GetFullNameWithHistory(year) << endl; 83 | } 84 | 85 | person.ChangeLastName(1961, "Ivanova"); 86 | cout << person.GetFullNameWithHistory(1967) << endl; 87 | 88 | return 0; 89 | } 90 | ``` 91 | 92 | ###### Вывод ###### 93 | ```objectivec 94 | Incognito 95 | Polina with unknown last name 96 | Polina Sergeeva 97 | Polina Sergeeva 98 | Appolinaria (Polina) Sergeeva 99 | Polina Volkova (Sergeeva) 100 | Appolinaria (Polina) Volkova (Sergeeva) 101 | Polina (Appolinaria, Polina) Volkova-Sergeeva (Volkova, Sergeeva) 102 | Pauline (Polina) with unknown last name 103 | Sergeeva with unknown first name 104 | Pauline (Polina) Sergeeva 105 | Pauline (Polina) Sergeeva (Ivanova, Sergeeva) 106 | ``` 107 | 108 | ##### Пояснение ##### 109 | В этой задаче вам надо прислать файл с реализацией класса *Person*. **Этот файл не должен содержать функцию main**. Если в нём будет функция *main*, вы получите ошибку компиляции. 110 | -------------------------------------------------------------------------------- /week-02/13-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | // ответ на запрос BUSES_FOR_STOP 9 | void PrintBusesForStop(const map>& buses_to_stops, 10 | map>& stops_to_buses, 11 | const string& stop) { 12 | if (stops_to_buses.count(stop) == 0) { 13 | cout << "No stop" << endl; 14 | } else { 15 | for (const string& bus : stops_to_buses[stop]) { 16 | cout << bus << " "; 17 | } 18 | cout << endl; 19 | } 20 | } 21 | 22 | // ответ на запрос STOPS_FOR_BUS 23 | void PrintStopsForBus(map>& buses_to_stops, 24 | map>& stops_to_buses, 25 | const string& bus) { 26 | if (buses_to_stops.count(bus) == 0) { 27 | cout << "No bus" << endl; 28 | } else { 29 | for (const string& stop : buses_to_stops[bus]) { 30 | cout << "Stop " << stop << ": "; 31 | 32 | // если через остановку проходит ровно один автобус, 33 | // то это наш автобус bus, следовательно, пересадки тут нет 34 | if (stops_to_buses[stop].size() == 1) { 35 | cout << "no interchange"; 36 | } else { 37 | for (const string& other_bus : stops_to_buses[stop]) { 38 | if (bus != other_bus) { 39 | cout << other_bus << " "; 40 | } 41 | } 42 | } 43 | cout << endl; 44 | } 45 | } 46 | } 47 | 48 | // ответ на запрос ALL_BUSES 49 | void PrintAllBuses(const map>& buses_to_stops) { 50 | if (buses_to_stops.empty()) { 51 | cout << "No buses" << endl; 52 | } else { 53 | for (const auto& bus_item : buses_to_stops) { 54 | cout << "Bus " << bus_item.first << ": "; 55 | for (const string& stop : bus_item.second) { 56 | cout << stop << " "; 57 | } 58 | cout << endl; 59 | } 60 | } 61 | } 62 | 63 | int main() { 64 | int q; 65 | cin >> q; 66 | 67 | map> buses_to_stops, stops_to_buses; 68 | 69 | for (int i = 0; i < q; ++i) { 70 | string operation_code; 71 | cin >> operation_code; 72 | 73 | if (operation_code == "NEW_BUS") { 74 | 75 | string bus; 76 | cin >> bus; 77 | int stop_count; 78 | cin >> stop_count; 79 | 80 | // с помощью ссылки дадим короткое название вектору 81 | // со списком остановок данного автобуса; 82 | // ключ bus изначально отсутствовал в словаре, поэтому он автоматически 83 | // добавится туда с пустым вектором в качестве значения 84 | vector& stops = buses_to_stops[bus]; 85 | stops.resize(stop_count); 86 | 87 | for (string& stop : stops) { 88 | cin >> stop; 89 | // не забудем обновить словарь stops_to_buses 90 | stops_to_buses[stop].push_back(bus); 91 | } 92 | 93 | } else if (operation_code == "BUSES_FOR_STOP") { 94 | 95 | string stop; 96 | cin >> stop; 97 | PrintBusesForStop(buses_to_stops, stops_to_buses, stop); 98 | 99 | } else if (operation_code == "STOPS_FOR_BUS") { 100 | 101 | string bus; 102 | cin >> bus; 103 | PrintStopsForBus(buses_to_stops, stops_to_buses, bus); 104 | 105 | } else if (operation_code == "ALL_BUSES") { 106 | 107 | PrintAllBuses(buses_to_stops); 108 | 109 | } 110 | } 111 | 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/rational_io.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | class Rational { 8 | public: 9 | Rational() { 10 | // Реализуйте конструктор по умолчанию 11 | p = 0; 12 | q = 1; 13 | } 14 | 15 | Rational(int numerator, int denominator) { 16 | // Реализуйте конструктор 17 | int a = numerator, b = denominator, c = 0; 18 | while (b != 0) { 19 | c = a % b; 20 | a = b; 21 | b = c; 22 | } 23 | p = numerator / a; 24 | q = denominator / a; 25 | } 26 | 27 | int Numerator() const { 28 | // Реализуйте этот метод 29 | return p; 30 | } 31 | 32 | int Denominator() const { 33 | // Реализуйте этот метод 34 | return q; 35 | } 36 | 37 | private: 38 | // Добавьте поля 39 | int p; 40 | int q; 41 | }; 42 | 43 | bool operator == (const Rational& lhs, const Rational& rhs) { 44 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 45 | while (b != 0) { 46 | c = a % b; 47 | a = b; 48 | b = c; 49 | } 50 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 51 | int l = n / lhs.Denominator(); 52 | int r = n / rhs.Denominator(); 53 | return (lhs.Numerator() * l) == (rhs.Numerator() *r); 54 | } 55 | 56 | Rational operator + (const Rational& lhs, const Rational& rhs) { 57 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 58 | while (b != 0) { 59 | c = a % b; 60 | a = b; 61 | b = c; 62 | } 63 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 64 | int l = n / lhs.Denominator(); 65 | int r = n / rhs.Denominator(); 66 | return Rational((lhs.Numerator() * l) + (rhs.Numerator() *r), n); 67 | } 68 | 69 | Rational operator - (const Rational& lhs, const Rational& rhs) { 70 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 71 | while (b != 0) { 72 | c = a % b; 73 | a = b; 74 | b = c; 75 | } 76 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 77 | int l = n / lhs.Denominator(); 78 | int r = n / rhs.Denominator(); 79 | return Rational((lhs.Numerator() * l) - (rhs.Numerator() *r), n); 80 | } 81 | 82 | Rational operator * (const Rational& lhs, const Rational& rhs) { 83 | return Rational(lhs.Numerator() * rhs.Numerator(), lhs.Denominator() * rhs.Denominator()); 84 | } 85 | 86 | Rational operator / (const Rational& lhs, const Rational& rhs) { 87 | return Rational(lhs.Numerator() * rhs.Denominator(), lhs.Denominator() * rhs.Numerator()); 88 | } 89 | 90 | ostream& operator << (ostream& out, const Rational& rational) { 91 | out << rational.Numerator() << '/' << rational.Denominator(); 92 | return out; 93 | } 94 | 95 | istream& operator >> (istream& in, Rational& rational) { 96 | int p; 97 | in >> p; 98 | in.ignore(1); 99 | int q; 100 | in >> q; 101 | rational = Rational(p, q); 102 | return in; 103 | } 104 | 105 | int main() { 106 | { 107 | ostringstream output; 108 | output << Rational(-6, 8); 109 | if (output.str() != "-3/4") { 110 | cout << "Rational(-6, 8) should be written as \"-3/4\"" << endl; 111 | return 1; 112 | } 113 | } 114 | 115 | { 116 | istringstream input("5/7"); 117 | Rational r; 118 | input >> r; 119 | bool equal = r == Rational(5, 7); 120 | if (!equal) { 121 | cout << "5/7 is incorrectly read as " << r << endl; 122 | return 2; 123 | } 124 | } 125 | 126 | { 127 | istringstream input("5/7 10/8"); 128 | Rational r1, r2; 129 | input >> r1 >> r2; 130 | bool correct = r1 == Rational(5, 7) && r2 == Rational(5, 4); 131 | if (!correct) { 132 | cout << "Multiple values are read incorrectly: " << r1 << " " << r2 << endl; 133 | return 3; 134 | } 135 | } 136 | 137 | cout << "OK" << endl; 138 | return 0; 139 | } 140 | -------------------------------------------------------------------------------- /week-03/05-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | vector FindNamesHistory(const map& names_by_year, 8 | int year) { 9 | vector names; 10 | // перебираем всю историю в хронологическом порядке 11 | for (const auto& item : names_by_year) { 12 | // если очередное имя не относится к будущему и отличается от предыдущего, 13 | if (item.first <= year && (names.empty() || names.back() != item.second)) { 14 | // добавляем его в историю 15 | names.push_back(item.second); 16 | } 17 | } 18 | return names; 19 | } 20 | 21 | string BuildJoinedName(vector names) { 22 | // нет истории — имя неизвестно 23 | if (names.empty()) { 24 | return ""; 25 | } 26 | // меняем прямой хронологический порядок на обратный 27 | reverse(begin(names), end(names)); 28 | 29 | // начинаем строить полное имя с самого последнего 30 | string joined_name = names[0]; 31 | 32 | // перебираем все последующие имена 33 | for (int i = 1; i < names.size(); ++i) { 34 | if (i == 1) { 35 | // если это первое «историческое» имя, отделяем его от последнего скобкой 36 | joined_name += " ("; 37 | } else { 38 | // если это не первое имя, отделяем от предыдущего запятой 39 | joined_name += ", "; 40 | } 41 | // и добавляем очередное имя 42 | joined_name += names[i]; 43 | } 44 | 45 | // если в истории было больше одного имени, мы открывали скобку — закроем её 46 | if (names.size() > 1) { 47 | joined_name += ")"; 48 | } 49 | // имя со всей историей готово 50 | return joined_name; 51 | } 52 | 53 | // см. решение предыдущей задачи 54 | string BuildFullName(const string& first_name, const string& last_name) { 55 | if (first_name.empty() && last_name.empty()) { 56 | return "Incognito"; 57 | } else if (first_name.empty()) { 58 | return last_name + " with unknown first name"; 59 | } else if (last_name.empty()) { 60 | return first_name + " with unknown last name"; 61 | } else { 62 | return first_name + " " + last_name; 63 | } 64 | } 65 | 66 | class Person { 67 | public: 68 | void ChangeFirstName(int year, const string& first_name) { 69 | first_names[year] = first_name; 70 | } 71 | void ChangeLastName(int year, const string& last_name) { 72 | last_names[year] = last_name; 73 | } 74 | 75 | string GetFullName(int year) { 76 | // найдём историю изменений имени и фамилии 77 | // в данном случае это излишне, так как нам достаточно узнать последние имя и фамилию, но почему бы не использовать готовые функции? 78 | const vector first_names_history = FindFirstNamesHistory(year); 79 | const vector last_names_history = FindLastNamesHistory(year); 80 | 81 | // подготовим данные для функции BuildFullName: возьмём последние имя и фамилию или оставим их пустыми, если они неизвестны 82 | string first_name; 83 | string last_name; 84 | if (!first_names_history.empty()) { 85 | first_name = first_names_history.back(); 86 | } 87 | if (!last_names_history.empty()) { 88 | last_name = last_names_history.back(); 89 | } 90 | return BuildFullName(first_name, last_name); 91 | } 92 | 93 | string GetFullNameWithHistory(int year) { 94 | // получим полное имя со всей историей 95 | const string first_name = BuildJoinedName(FindFirstNamesHistory(year)); 96 | // получим полную фамилию со всей историей 97 | const string last_name = BuildJoinedName(FindLastNamesHistory(year)); 98 | // объединим их с помощью готовой функции 99 | return BuildFullName(first_name, last_name); 100 | } 101 | 102 | private: 103 | vector FindFirstNamesHistory(int year) { 104 | return FindNamesHistory(first_names, year); 105 | } 106 | vector FindLastNamesHistory(int year) { 107 | return FindNamesHistory(last_names, year); 108 | } 109 | 110 | map first_names; 111 | map last_names; 112 | }; 113 | -------------------------------------------------------------------------------- /week-04/11-Practice-Programming-Assignment/rational_calc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | int GreatestCommonDivisor(int a, int b) { 7 | int n = a, m = b, c = 0; 8 | while (m != 0) { 9 | c = n % m; 10 | n = m; 11 | m = c; 12 | } 13 | return n; 14 | } 15 | 16 | class Rational { 17 | public: 18 | Rational() { 19 | // Реализуйте конструктор по умолчанию 20 | p = 0; 21 | q = 1; 22 | } 23 | 24 | Rational(int numerator, int denominator) { 25 | if (denominator == 0) { 26 | throw invalid_argument("Invalid argument"); 27 | } 28 | // Реализуйте конструктор 29 | const int gcd = GreatestCommonDivisor(numerator, denominator); 30 | if (denominator / gcd < 0) { 31 | denominator = -denominator; 32 | numerator = -numerator; 33 | } 34 | p = numerator / gcd; 35 | q = denominator / gcd; 36 | } 37 | 38 | int Numerator() const { 39 | // Реализуйте этот метод 40 | return p; 41 | } 42 | 43 | int Denominator() const { 44 | // Реализуйте этот метод 45 | return q; 46 | } 47 | 48 | private: 49 | // Добавьте поля 50 | int p; 51 | int q; 52 | }; 53 | 54 | bool operator == (const Rational& lhs, const Rational& rhs) { 55 | const int gcd = GreatestCommonDivisor(lhs.Denominator(), rhs.Denominator()); 56 | int n = (lhs.Denominator() * rhs.Denominator()) / gcd; 57 | int l = n / lhs.Denominator(); 58 | int r = n / rhs.Denominator(); 59 | return (lhs.Numerator() * l) == (rhs.Numerator() *r); 60 | } 61 | 62 | bool operator < (const Rational& lhs, const Rational& rhs) { 63 | const int gcd = GreatestCommonDivisor(lhs.Denominator(), rhs.Denominator()); 64 | int n = (lhs.Denominator() * rhs.Denominator()) / gcd; 65 | int l = n / lhs.Denominator(); 66 | int r = n / rhs.Denominator(); 67 | return (lhs.Numerator() * l) < (rhs.Numerator() *r); 68 | } 69 | 70 | Rational operator + (const Rational& lhs, const Rational& rhs) { 71 | const int gcd = GreatestCommonDivisor(lhs.Denominator(), rhs.Denominator()); 72 | int n = (lhs.Denominator() * rhs.Denominator()) / gcd; 73 | int l = n / lhs.Denominator(); 74 | int r = n / rhs.Denominator(); 75 | return Rational((lhs.Numerator() * l) + (rhs.Numerator() *r), n); 76 | } 77 | 78 | Rational operator - (const Rational& lhs, const Rational& rhs) { 79 | const int gcd = GreatestCommonDivisor(lhs.Denominator(), rhs.Denominator()); 80 | int n = (lhs.Denominator() * rhs.Denominator()) / gcd; 81 | int l = n / lhs.Denominator(); 82 | int r = n / rhs.Denominator(); 83 | return Rational((lhs.Numerator() * l) - (rhs.Numerator() *r), n); 84 | } 85 | 86 | Rational operator * (const Rational& lhs, const Rational& rhs) { 87 | return Rational(lhs.Numerator() * rhs.Numerator(), lhs.Denominator() * rhs.Denominator()); 88 | } 89 | 90 | Rational operator / (const Rational& lhs, const Rational& rhs) { 91 | if (rhs.Numerator() == 0) { 92 | throw domain_error("Division by zero"); 93 | } 94 | return Rational(lhs.Numerator() * rhs.Denominator(), lhs.Denominator() * rhs.Numerator()); 95 | } 96 | 97 | ostream& operator << (ostream& out, const Rational& rational) { 98 | out << rational.Numerator() << '/' << rational.Denominator(); 99 | return out; 100 | } 101 | 102 | istream& operator >> (istream& in, Rational& rational) { 103 | int p; 104 | in >> p; 105 | in.ignore(1); 106 | int q; 107 | in >> q; 108 | rational = Rational(p, q); 109 | return in; 110 | } 111 | 112 | int main() { 113 | 114 | Rational r1, r2; 115 | char operation; 116 | try { 117 | cin >> r1 >> operation >> r2; 118 | if (operation == '+') { 119 | cout << r1 + r2 << endl; 120 | } else if (operation == '-') { 121 | cout << r1 - r2 << endl; 122 | } else if (operation == '*') { 123 | cout << r1 * r2 << endl; 124 | } else if (operation == '/') { 125 | try { 126 | cout << r1 / r2 << endl; 127 | } catch (domain_error& de) { 128 | cout << de.what(); 129 | } 130 | } 131 | } catch (invalid_argument& ia) { 132 | cout << ia.what(); 133 | } 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/rational_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | 10 | 11 | class Rational { 12 | public: 13 | Rational() { 14 | // Реализуйте конструктор по умолчанию 15 | p = 0; 16 | q = 1; 17 | } 18 | 19 | Rational(int numerator, int denominator) { 20 | // Реализуйте конструктор 21 | int a = numerator, b = denominator, c = 0; 22 | while (b != 0) { 23 | c = a % b; 24 | a = b; 25 | b = c; 26 | } 27 | if (denominator / a < 0) { 28 | denominator = -denominator; 29 | numerator = -numerator; 30 | } 31 | p = numerator / a; 32 | q = denominator / a; 33 | } 34 | 35 | int Numerator() const { 36 | // Реализуйте этот метод 37 | return p; 38 | } 39 | 40 | int Denominator() const { 41 | // Реализуйте этот метод 42 | return q; 43 | } 44 | 45 | private: 46 | // Добавьте поля 47 | int p; 48 | int q; 49 | }; 50 | 51 | bool operator == (const Rational& lhs, const Rational& rhs) { 52 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 53 | while (b != 0) { 54 | c = a % b; 55 | a = b; 56 | b = c; 57 | } 58 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 59 | int l = n / lhs.Denominator(); 60 | int r = n / rhs.Denominator(); 61 | return (lhs.Numerator() * l) == (rhs.Numerator() *r); 62 | } 63 | 64 | bool operator < (const Rational& lhs, const Rational& rhs) { 65 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 66 | while (b != 0) { 67 | c = a % b; 68 | a = b; 69 | b = c; 70 | } 71 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 72 | int l = n / lhs.Denominator(); 73 | int r = n / rhs.Denominator(); 74 | return (lhs.Numerator() * l) < (rhs.Numerator() *r); 75 | } 76 | 77 | Rational operator + (const Rational& lhs, const Rational& rhs) { 78 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 79 | while (b != 0) { 80 | c = a % b; 81 | a = b; 82 | b = c; 83 | } 84 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 85 | int l = n / lhs.Denominator(); 86 | int r = n / rhs.Denominator(); 87 | return Rational((lhs.Numerator() * l) + (rhs.Numerator() *r), n); 88 | } 89 | 90 | Rational operator - (const Rational& lhs, const Rational& rhs) { 91 | int a = lhs.Denominator(), b = rhs.Denominator(), c = 0; 92 | while (b != 0) { 93 | c = a % b; 94 | a = b; 95 | b = c; 96 | } 97 | int n = (lhs.Denominator() * rhs.Denominator()) / a; 98 | int l = n / lhs.Denominator(); 99 | int r = n / rhs.Denominator(); 100 | return Rational((lhs.Numerator() * l) - (rhs.Numerator() *r), n); 101 | } 102 | 103 | Rational operator * (const Rational& lhs, const Rational& rhs) { 104 | return Rational(lhs.Numerator() * rhs.Numerator(), lhs.Denominator() * rhs.Denominator()); 105 | } 106 | 107 | Rational operator / (const Rational& lhs, const Rational& rhs) { 108 | return Rational(lhs.Numerator() * rhs.Denominator(), lhs.Denominator() * rhs.Numerator()); 109 | } 110 | 111 | ostream& operator << (ostream& out, const Rational& rational) { 112 | out << rational.Numerator() << '/' << rational.Denominator(); 113 | return out; 114 | } 115 | 116 | istream& operator >> (istream& in, Rational& rational) { 117 | int p; 118 | in >> p; 119 | in.ignore(1); 120 | int q; 121 | in >> q; 122 | rational = Rational(p, q); 123 | return in; 124 | } 125 | 126 | int main() { 127 | { 128 | const set rs = {{1, 2}, {1, 25}, {3, 4}, {3, 4}, {1, 2}}; 129 | if (rs.size() != 3) { 130 | cout << "Wrong amount of items in the set" << endl; 131 | return 1; 132 | } 133 | 134 | vector v; 135 | for (auto x : rs) { 136 | v.push_back(x); 137 | } 138 | if (v != vector{{1, 25}, {1, 2}, {3, 4}}) { 139 | cout << "Rationals comparison works incorrectly" << endl; 140 | return 2; 141 | } 142 | } 143 | 144 | { 145 | map count; 146 | ++count[{1, 2}]; 147 | ++count[{1, 2}]; 148 | 149 | ++count[{2, 3}]; 150 | 151 | if (count.size() != 2) { 152 | cout << "Wrong amount of items in the map" << endl; 153 | return 3; 154 | } 155 | } 156 | 157 | cout << "OK" << endl; 158 | return 0; 159 | } 160 | -------------------------------------------------------------------------------- /week-02/12-Practice-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Тренировочное задание по программированию: Справочник столиц #### 2 | 3 | Реализуйте справочник столиц стран. 4 | 5 | На вход программе поступают следующие запросы: 6 | 7 | * **CHANGE_CAPITAL *country new_capital*** — изменение столицы страны ***country*** на ***new_capital***, либо добавление такой страны с такой столицей, если раньше её не было. 8 | * **RENAME *old_country_name new_country_name*** — переименование страны из ***old_country_name*** в ***new_country_name***. 9 | * **ABOUT *country*** — вывод столицы страны ***country***. 10 | * **DUMP** — вывод столиц всех стран. 11 | 12 | ##### Формат ввода ##### 13 | В первой строке содержится количество запросов *Q*, в следующих *Q* строках — описания запросов. Все названия стран и столиц состоят лишь из латинских букв, цифр и символов подчёркивания. 14 | 15 | ##### Формат вывода ##### 16 | Выведите результат обработки каждого запроса: 17 | 18 | В ответ на запрос **CHANGE_CAPITAL *country* *new_capital*** выведите 19 | 20 | * **Introduce new country *country* with capital *new_capital***, если страны ***country*** раньше не существовало; 21 | * **Country *country* hasn't changed its capital**, если страна ***country*** до текущего момента имела столицу ***new_capital***; 22 | * **Country *country* has changed its capital from *old_capital* to *new_capital***, если страна ***country*** до текущего момента имела столицу ***old_capital***, название которой не совпадает с названием ***new_capital***. 23 | 24 | В ответ на запрос **RENAME *old_country_name* *new_country_name*** выведите 25 | 26 | * **Incorrect rename, skip**, если новое название страны совпадает со старым, страна ***old_country_name*** не существует или страна ***new_country_name*** уже существует; 27 | * **Country *old_country_name* with capital *capital* has been renamed to *new_country_name***, если запрос корректен и страна имеет столицу ***capital***. 28 | 29 | В ответ на запрос **ABOUT *country*** выведите 30 | 31 | * **Country *country* doesn't exist**, если страны с названием ***country*** не существует; 32 | * **Country *country* has capital *capital***, если страна ***country*** существует и имеет столицу ***capital***. 33 | 34 | В ответ на запрос **DUMP** выведите 35 | 36 | * **There are no countries in the world**, если пока не было добавлено ни одной страны; 37 | * разделённые пробелами пары ***country/capital***, описывающие столицы всех стран и упорядоченные по названию страны, если в мире уже есть хотя бы одна страна. 38 | 39 | ##### Пример 1 ##### 40 | ###### Ввод ###### 41 | ```objectivec 42 | 6 43 | CHANGE_CAPITAL RussianEmpire Petrograd 44 | RENAME RussianEmpire RussianRepublic 45 | ABOUT RussianRepublic 46 | RENAME RussianRepublic USSR 47 | CHANGE_CAPITAL USSR Moscow 48 | DUMP 49 | ``` 50 | 51 | ###### Вывод ###### 52 | ```objectivec 53 | Introduce new country RussianEmpire with capital Petrograd 54 | Country RussianEmpire with capital Petrograd has been renamed to RussianRepublic 55 | Country RussianRepublic has capital Petrograd 56 | Country RussianRepublic with capital Petrograd has been renamed to USSR 57 | Country USSR has changed its capital from Petrograd to Moscow 58 | USSR/Moscow 59 | ``` 60 | ##### Пример 2 ##### 61 | ###### Ввод ###### 62 | ```objectivec 63 | RENAME FakeCountry FarFarAway 64 | ABOUT FarFarAway 65 | DUMP 66 | CHANGE_CAPITAL TsardomOfRussia Moscow 67 | CHANGE_CAPITAL TsardomOfRussia Moscow 68 | CHANGE_CAPITAL ColonialBrazil Salvador 69 | CHANGE_CAPITAL TsardomOfRussia SaintPetersburg 70 | RENAME TsardomOfRussia RussianEmpire 71 | CHANGE_CAPITAL RussianEmpire Moscow 72 | CHANGE_CAPITAL RussianEmpire SaintPetersburg 73 | CHANGE_CAPITAL ColonialBrazil RioDeJaneiro 74 | DUMP 75 | RENAME ColonialBrazil EmpireOfBrazil 76 | ABOUT RussianEmpire 77 | RENAME EmpireOfBrazil UnitedStatesOfBrazil 78 | CHANGE_CAPITAL RussianEmpire Petrograd 79 | RENAME RussianEmpire RussianRepublic 80 | RENAME RussianRepublic USSR 81 | CHANGE_CAPITAL USSR Moscow 82 | CHANGE_CAPITAL UnitedStatesOfBrazil Brasilia 83 | RENAME UnitedStatesOfBrazil FederativeRepublicOfBrazil 84 | ABOUT RussianEmpire 85 | DUMP 86 | RENAME USSR USSR 87 | ``` 88 | 89 | ###### Вывод ###### 90 | ```objectivec 91 | Incorrect rename, skip 92 | Country FarFarAway doesn't exist 93 | There are no countries in the world 94 | Introduce new country TsardomOfRussia with capital Moscow 95 | Country TsardomOfRussia hasn't changed its capital 96 | Introduce new country ColonialBrazil with capital Salvador 97 | Country TsardomOfRussia has changed its capital from Moscow to SaintPetersburg 98 | Country TsardomOfRussia with capital SaintPetersburg has been renamed to RussianEmpire 99 | Country RussianEmpire has changed its capital from SaintPetersburg to Moscow 100 | Country RussianEmpire has changed its capital from Moscow to SaintPetersburg 101 | Country ColonialBrazil has changed its capital from Salvador to RioDeJaneiro 102 | ColonialBrazil/RioDeJaneiro RussianEmpire/SaintPetersburg 103 | Country ColonialBrazil with capital RioDeJaneiro has been renamed to EmpireOfBrazil 104 | Country RussianEmpire has capital SaintPetersburg 105 | Country EmpireOfBrazil with capital RioDeJaneiro has been renamed to UnitedStatesOfBrazil 106 | Country RussianEmpire has changed its capital from SaintPetersburg to Petrograd 107 | Country RussianEmpire with capital Petrograd has been renamed to RussianRepublic 108 | Country RussianRepublic with capital Petrograd has been renamed to USSR 109 | Country USSR has changed its capital from Petrograd to Moscow 110 | Country UnitedStatesOfBrazil has changed its capital from RioDeJaneiro to Brasilia 111 | Country UnitedStatesOfBrazil with capital Brasilia has been renamed to FederativeRepublicOfBrazil 112 | Country RussianEmpire doesn't exist 113 | FederativeRepublicOfBrazil/Brasilia USSR/Moscow 114 | Incorrect rename, skip 115 | ``` 116 | -------------------------------------------------------------------------------- /week-04/08-Programming-Assignment/README.md: -------------------------------------------------------------------------------- 1 | #### Задание по программированию: Класс Rational #### 2 | 3 | ##### Общее описание ##### 4 | В этой задаче вам надо разработать класс для представления рациональных чисел и внедрить его в систему типов языка С++ так, чтобы им можно было пользоваться естественным образом. Задание состоит из нескольких частей. К каждой части приложен файл с заготовкой программы, который имеет следующую структуру 5 | ```objectivec 6 | #include 7 | using namespace std; 8 | 9 | // Комментарии, которые говорят, что именно нужно реализовать в этой программе 10 | 11 | int main() { 12 | // Набор юнит-тестов для вашей реализации 13 | cout << "OK" << endl; 14 | return 0; 15 | } 16 | ``` 17 | Вам нужно, **не меняя тело функции main**, реализовать то, что предложено в комментариях, так, чтобы ваша программа выводила на экран сообщение OK. Функция main содержит ряд юнит-тестов, которые проверяют правильность вашей реализации. Если эти тесты находят ошибку в вашей реализации, то вместо OK программа выведет подсказку о том, что именно работает неправильно. 18 | 19 | Когда ваша программа начнёт выводить OK, можете отправлять свой файл на проверку. Ваша реализация будет тестироваться на другом, более полном наборе тестов. **То есть, если ваша программа выводит OK, то это не даёт гарантии, что ваша реализация будет принята тестирующей системой**. В случае неудачной посылки тестирующая система также выдаст вам подсказку о том, какая именно часть реализации работает неправильно. 20 | 21 | На проверку можно отправлять весь файл с вашей реализацией: функцию *main* удалять из него не нужно. 22 | 23 | ##### Часть 1 ##### 24 | В первой части вам надо реализовать класс *Rational*, который представляет собой рациональное число вида *p/q*, где *p* целое, а *q* натуральное. Он должен иметь следующий интерфейс: 25 | ```objectivec 26 | class Rational { 27 | public: 28 | Rational(); 29 | Rational(int numerator, int denominator); 30 | 31 | int Numerator() const; 32 | int Denominator() const; 33 | }; 34 | ``` 35 | Класс *Rational* должен гарантировать, что *p/q* — это несократимая дробь. Например, код 36 | ```objectivec 37 | Rational r(4, 6); 38 | cout << r.Numerator() << '/' << r.Denominator(); 39 | ``` 40 | должен выводить «2/3» — именно поэтому мы делаем *Rational* классом, а не структурой. Структура позволила бы нарушить этот инвариант: 41 | ```objectivec 42 | struct Rational { 43 | int numerator, denominator; 44 | }; 45 | 46 | Rational r{2, 3}; 47 | r.numerator = 6; // Нарушен инвариант несократимости 48 | ``` 49 | 50 | Список требований, предъявляемых к реализации интерфейса класса *Rational*: 51 | 52 | 1. Конструктор по умолчанию должен создавать дробь с числителем *0* и знаменателем *1*. 53 | 2. При конструировании объека класса Rational с параметрами *p* и *q* должно выполняться сокращение дроби *p/q* (здесь вам может пригодиться решение задачи «Наибольший общий делитель»). 54 | 3. Если дробь *p/q* отрицательная, то объект *Rational(p, q)* должен иметь отрицательный числитель и положительный знаменатель. 55 | 4. Если дробь *p/q* положительная, то объект *Rational(p, q)* должен иметь положительные числитель и знаменатель (обратите внимание на случай *Rational(-2, -3)*). 56 | 5. Если числитель дроби равен нулю, то знаменатель должен быть равен *1*. 57 | 58 | **Гарантируется, что ни в одном из тестов, на которых будет тестироваться ваша реализация, не будет знаменателя, равного нулю.** 59 | 60 | Шаблон программы: 61 | 62 | [rational_interface.cpp](https://github.com/avtomato/Basics-of-C-plus-plus-development-white-belt/blob/master/week-04/08-Programming-Assignment/Source/rational_interface.cpp) 63 | 64 | ##### Часть 2 ##### 65 | Реализуйте для класса *Rational* операторы ==, + и - так, чтобы операции с дробями можно было записывать естественным образом. Например, следующий код должен быть валидным: 66 | ```objectivec 67 | const Rational r = Rational(1, 2) + Rational(1, 3) - Rational(1, 4); 68 | if (r == Rational(7, 12)) { 69 | cout << "equal"; 70 | } 71 | ``` 72 | Шаблон программы: 73 | 74 | [rational_eq_add_sub.cpp](https://github.com/avtomato/Basics-of-C-plus-plus-development-white-belt/blob/master/week-04/08-Programming-Assignment/Source/rational_eq_add_sub.cpp) 75 | 76 | ##### Часть 3 ##### 77 | Аналогично предыдущей части, реализуйте операторы * и /. Например, следующий код должен быть валидным: 78 | ```objectivec 79 | const Rational r = Rational(1, 2) * Rational(1, 3) / Rational(1, 4); 80 | if (r == Rational(2, 3)) { 81 | cout << "equal"; 82 | } 83 | ``` 84 | **Гарантируется, что ни в одном из тестов, на которых будет тестироваться ваша реализация, не будет выполняться деление на ноль.** 85 | 86 | Шаблон программы: 87 | 88 | [rational_mult_div.cpp](https://github.com/avtomato/Basics-of-C-plus-plus-development-white-belt/blob/master/week-04/08-Programming-Assignment/Source/rational_mult_div.cpp) 89 | 90 | ##### Часть 4 ##### 91 | В этой части вам нужно реализовать операторы ввода и вывода для класса *Rational*. В результате у вас должен работать, например, такой код 92 | ```objectivec 93 | Rational r; 94 | cin >> r; 95 | cout << r; 96 | ``` 97 | Шаблон программы: 98 | 99 | [rational_io.cpp](https://github.com/avtomato/Basics-of-C-plus-plus-development-white-belt/blob/master/week-04/08-Programming-Assignment/Source/rational_io.cpp) 100 | 101 | ##### Часть 5 ##### 102 | Наконец, вам нужно реализовать возможность использовать объекты класса *Rational* в качестве элементов контейнера *set* и ключей в контейнере *map*. Пример: 103 | ```objectivec 104 | set rationals; 105 | rationals.insert(Rational(1, 2)); 106 | rationals.insert(Rational(1, 3)); 107 | 108 | map name; 109 | name[Rational(1, 2)] = "одна вторая"; 110 | ``` 111 | Шаблон программы: 112 | 113 | [rational_map.cpp](https://github.com/avtomato/Basics-of-C-plus-plus-development-white-belt/blob/master/week-04/08-Programming-Assignment/Source/rational_map.cpp) 114 | -------------------------------------------------------------------------------- /week-05/01-Programming-Assignment/Solution/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | class Date { 14 | public: 15 | // конструктор выбрасывает исключение, если его аргументы некорректны 16 | Date(int new_year, int new_month, int new_day) { 17 | year = new_year; 18 | if (new_month > 12 || new_month < 1) { 19 | throw logic_error("Month value is invalid: " + to_string(new_month)); 20 | } 21 | month = new_month; 22 | if (new_day > 31 || new_day < 1) { 23 | throw logic_error("Day value is invalid: " + to_string(new_day)); 24 | } 25 | day = new_day; 26 | } 27 | 28 | int GetYear() const { 29 | return year; 30 | } 31 | int GetMonth() const { 32 | return month; 33 | } 34 | int GetDay() const { 35 | return day; 36 | } 37 | 38 | private: 39 | int year; 40 | int month; 41 | int day; 42 | }; 43 | 44 | // определить сравнение для дат необходимо для использования их в качестве ключей словаря 45 | bool operator<(const Date& lhs, const Date& rhs) { 46 | // воспользуемся тем фактом, что векторы уже можно сравнивать на <: 47 | // создадим вектор из года, месяца и дня для каждой даты и сравним их 48 | return vector{lhs.GetYear(), lhs.GetMonth(), lhs.GetDay()} < 49 | vector{rhs.GetYear(), rhs.GetMonth(), rhs.GetDay()}; 50 | } 51 | 52 | // даты будут по умолчанию выводиться в нужном формате 53 | ostream& operator<<(ostream& stream, const Date& date) { 54 | stream << setw(4) << setfill('0') << date.GetYear() << 55 | "-" << setw(2) << setfill('0') << date.GetMonth() << 56 | "-" << setw(2) << setfill('0') << date.GetDay(); 57 | return stream; 58 | } 59 | 60 | class Database { 61 | public: 62 | void AddEvent(const Date& date, const string& event) { 63 | storage[date].insert(event); 64 | } 65 | 66 | bool DeleteEvent(const Date& date, const string& event) { 67 | if (storage.count(date) > 0 && storage[date].count(event) > 0) { 68 | storage[date].erase(event); 69 | return true; 70 | } 71 | return false; 72 | } 73 | 74 | int DeleteDate(const Date& date) { 75 | if (storage.count(date) == 0) { 76 | return 0; 77 | } else { 78 | const int event_count = storage[date].size(); 79 | storage.erase(date); 80 | return event_count; 81 | } 82 | } 83 | 84 | set Find(const Date& date) const { 85 | if (storage.count(date) > 0) { 86 | return storage.at(date); 87 | } else { 88 | return {}; 89 | } 90 | } 91 | 92 | void Print() const { 93 | for (const auto& item : storage) { 94 | for (const string& event : item.second) { 95 | cout << item.first << " " << event << endl; 96 | } 97 | } 98 | } 99 | 100 | private: 101 | map> storage; 102 | }; 103 | 104 | Date ParseDate(const string& date) { 105 | stringstream date_stream(date); 106 | 107 | int year; 108 | date_stream >> year; 109 | 110 | if (date_stream.peek() != '-') { 111 | throw logic_error("Wrong date format: " + date); 112 | } 113 | date_stream.ignore(); 114 | 115 | int month; 116 | date_stream >> month; 117 | 118 | if (date_stream.peek() != '-') { 119 | throw logic_error("Wrong date format: " + date); 120 | } 121 | date_stream.ignore(); 122 | 123 | int day; 124 | date_stream >> day; 125 | 126 | if (!date_stream.eof()) { 127 | throw logic_error("Wrong date format: " + date); 128 | } 129 | 130 | return Date(year, month, day); 131 | } 132 | 133 | int main() { 134 | try { 135 | Database db; 136 | 137 | string command_line; 138 | while (getline(cin, command_line)) { 139 | stringstream ss(command_line); 140 | 141 | string command; 142 | ss >> command; 143 | 144 | if (command == "Add") { 145 | 146 | string date_str, event; 147 | ss >> date_str >> event; 148 | const Date date = ParseDate(date_str); 149 | db.AddEvent(date, event); 150 | 151 | } else if (command == "Del") { 152 | 153 | string date_str; 154 | ss >> date_str; 155 | string event; 156 | if (!ss.eof()) { 157 | ss >> event; 158 | } 159 | const Date date = ParseDate(date_str); 160 | if (event.empty()) { 161 | const int count = db.DeleteDate(date); 162 | cout << "Deleted " << count << " events" << endl; 163 | } else { 164 | if (db.DeleteEvent(date, event)) { 165 | cout << "Deleted successfully" << endl; 166 | } else { 167 | cout << "Event not found" << endl; 168 | } 169 | } 170 | 171 | } else if (command == "Find") { 172 | 173 | string date_str; 174 | ss >> date_str; 175 | const Date date = ParseDate(date_str); 176 | for (const string& event : db.Find(date)) { 177 | cout << event << endl; 178 | } 179 | 180 | } else if (command == "Print") { 181 | 182 | db.Print(); 183 | 184 | } else if (command.empty()) { 185 | 186 | break; 187 | 188 | } else { 189 | 190 | throw logic_error("Unknown command: " + command); 191 | 192 | } 193 | } 194 | } catch (const exception& e) { 195 | cout << e.what() << endl; 196 | } 197 | 198 | return 0; 199 | } 200 | -------------------------------------------------------------------------------- /week-03/07-Programming-Assignment/names3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | 10 | string FindNameByYear(int year, const map& names) { 11 | string name; // изначально имя неизвестно 12 | 13 | // перебираем всю историю по возрастанию ключа словаря, то есть в хронологическом порядке 14 | for (const auto& item : names) { 15 | // если очередной год не больше данного, обновляем имя 16 | if (item.first <= year) { 17 | name = item.second; 18 | } else { 19 | // иначе пора остановиться, так как эта запись и все последующие относятся к будущему 20 | break; 21 | } 22 | } 23 | 24 | return name; 25 | } 26 | 27 | string GetHistory(int year, const map& names) { 28 | vector names_history; 29 | string current_name = ""; 30 | 31 | for (const auto& item : names) { 32 | if (item.first <= year) { 33 | if (item.second != current_name) { 34 | vector v = {item.second}; 35 | names_history.insert(begin(names_history), begin(v), end(v)); 36 | current_name = item.second; 37 | } 38 | } else { 39 | break; 40 | } 41 | } 42 | 43 | string history = ""; 44 | 45 | for (int i = 1; i < names_history.size(); ++i) { 46 | if (history.size() == 0) { 47 | history += names_history[i]; 48 | } else { 49 | history = history + ", " + names_history[i]; 50 | } 51 | } 52 | 53 | return history; 54 | } 55 | 56 | class Person { 57 | public: 58 | Person (const string& first_name, const string& last_name, int year) { 59 | year_of_birth = year; 60 | firstname[year] = first_name; 61 | lastname[year] = last_name; 62 | } 63 | void ChangeFirstName(int year, const string& first_name) { 64 | // добавить факт изменения имени на first_name в год year 65 | if (year < year_of_birth) { 66 | 67 | } else { 68 | firstname[year] = first_name; 69 | } 70 | } 71 | void ChangeLastName(int year, const string& last_name) { 72 | // добавить факт изменения фамилии на last_name в год year 73 | if (year < year_of_birth) { 74 | 75 | } else { 76 | lastname[year] = last_name; 77 | } 78 | } 79 | string GetFullName(int year) const { 80 | // получить имя и фамилию по состоянию на конец года year 81 | if (year < year_of_birth) { 82 | return "No person"; 83 | } 84 | const string first_name = FindNameByYear(year, firstname); 85 | const string last_name = FindNameByYear(year, lastname); 86 | string full_name = first_name + " " + last_name; 87 | if (first_name.size() == 0 && last_name.size() == 0) { 88 | full_name = "Incognito"; 89 | return full_name; 90 | } else if (first_name.size() == 0) { 91 | full_name = last_name + " with unknown first name"; 92 | return full_name; 93 | } else if (last_name.size() == 0) { 94 | full_name = first_name + " with unknown last name"; 95 | return full_name; 96 | } 97 | return full_name; 98 | } 99 | string GetFullNameWithHistory(int year) const { 100 | if (year < year_of_birth) { 101 | return "No person"; 102 | } 103 | // получить все имена и фамилии по состоянию на конец года year 104 | const string first_name = FindNameByYear(year, firstname); 105 | const string last_name = FindNameByYear(year, lastname); 106 | const string history_first_name = GetHistory(year, firstname); 107 | const string history_last_name = GetHistory(year, lastname); 108 | 109 | string full_name = first_name + " (" + history_first_name + ")" + " " + last_name + " (" + history_last_name + ")"; 110 | 111 | if (first_name.size() == 0 && last_name.size() == 0) { 112 | full_name = "Incognito"; 113 | return full_name; 114 | } else if (first_name.size() == 0) { 115 | if (history_last_name.size() == 0) { 116 | full_name = last_name + " with unknown first name"; 117 | return full_name; 118 | } else { 119 | full_name = last_name + " (" + history_last_name + ")" + " with unknown first name"; 120 | return full_name; 121 | } 122 | } else if (last_name.size() == 0) { 123 | if (history_first_name.size() == 0) { 124 | full_name = first_name + " with unknown last name"; 125 | return full_name; 126 | } else { 127 | full_name = first_name + " (" + history_first_name + ")" + " with unknown last name"; 128 | return full_name; 129 | } 130 | } else if (history_first_name.size() == 0 && history_last_name.size() == 0) { 131 | full_name = first_name + " " + last_name; 132 | return full_name; 133 | }else if (history_first_name.size() == 0) { 134 | full_name = first_name + " " + last_name + " (" + history_last_name + ")" ; 135 | return full_name; 136 | } else if (history_last_name.size() == 0) { 137 | full_name = first_name + " (" + history_first_name + ") " + last_name; 138 | return full_name; 139 | } 140 | return full_name; 141 | } 142 | 143 | private: 144 | // приватные поля 145 | map firstname; 146 | map lastname; 147 | int year_of_birth; 148 | }; 149 | 150 | int main() { 151 | Person person("Polina", "Sergeeva", 1960); 152 | for (int year : {1959, 1960}) { 153 | cout << person.GetFullNameWithHistory(year) << endl; 154 | } 155 | 156 | person.ChangeFirstName(1965, "Appolinaria"); 157 | person.ChangeLastName(1967, "Ivanova"); 158 | for (int year : {1965, 1967}) { 159 | cout << person.GetFullNameWithHistory(year) << endl; 160 | } 161 | 162 | return 0; 163 | } 164 | --------------------------------------------------------------------------------