├── Brown Belt ├── Readme.md ├── Week_1 │ ├── Readme.md │ ├── Task_1 │ │ ├── Task_1.cpp │ │ └── test_runner.h │ ├── Task_2 │ │ ├── Task_2.cpp │ │ └── test_runner.h │ ├── Task_3 │ │ ├── Task_3.cpp │ │ └── test_runner.h │ ├── Task_4 │ │ ├── Task_4.cpp │ │ └── test_runner.h │ └── Task_5 │ │ ├── Task_5.cpp │ │ └── test_runner.h ├── Week_2 │ ├── Readme.md │ ├── Task_1 │ │ ├── Task_1.cpp │ │ ├── test_runner.h │ │ ├── xml.cpp │ │ └── xml.h │ ├── Task_2 │ │ ├── Task_2.cpp │ │ ├── json.cpp │ │ ├── json.h │ │ └── test_runner.h │ ├── Task_3 │ │ ├── Task_3.cpp │ │ ├── ini.cpp │ │ ├── ini.h │ │ └── test_runner.h │ ├── Task_4 │ │ ├── Task_4.cpp │ │ ├── json.cpp │ │ ├── json.h │ │ ├── refactoring.cpp │ │ ├── test_runner.h │ │ ├── xml.cpp │ │ └── xml.h │ ├── Task_5 │ │ ├── Task_5.cpp │ │ ├── stats_aggregator.cpp │ │ ├── stats_aggregator.h │ │ ├── stats_aggregator_test.cpp │ │ └── test_runner.h │ ├── Task_6 │ │ ├── Task_6.cpp │ │ ├── game_object.h │ │ ├── geo2d.cpp │ │ ├── geo2d.h │ │ └── test_runner.h │ └── Task_7 │ │ ├── Task_7.cpp │ │ └── test_runner.h └── Week_3 │ ├── Task_1 │ ├── Task_1.cpp │ ├── Task_1.vcxproj │ ├── Task_1.vcxproj.filters │ └── Task_1.vcxproj.user │ ├── Task_2 │ ├── Task_2.cpp │ ├── Task_2.vcxproj │ ├── Task_2.vcxproj.filters │ ├── Task_2.vcxproj.user │ └── test_runner.h │ ├── Task_3 │ ├── Task_3.cpp │ ├── Task_3.vcxproj │ ├── Task_3.vcxproj.filters │ ├── Task_3.vcxproj.user │ └── test_runner.h │ ├── Task_6 │ ├── Task_6.cpp │ ├── Task_6.vcxproj │ ├── Task_6.vcxproj.filters │ ├── Task_6.vcxproj.user │ └── test_runner.h │ └── Task_7 │ ├── Task_7.cpp │ ├── Task_7.vcxproj │ ├── Task_7.vcxproj.filters │ ├── Task_7.vcxproj.user │ ├── animals.h │ └── test_runner.h ├── README.md ├── Red Belt ├── Readme.md ├── Week_1 │ ├── Readme.md │ ├── Task_1 │ │ ├── Task_1.cpp │ │ └── Test_runner.h │ ├── Task_2 │ │ ├── Task_2.cpp │ │ └── test_runner.h │ ├── Task_3 │ │ ├── Task_3.cpp │ │ └── airline_ticket.h │ ├── Task_4 │ │ ├── Task_4.cpp │ │ ├── airline_ticket.h │ │ └── test_runner.h │ ├── Task_5 │ │ ├── Task_5.cpp │ │ └── test_runner.h │ ├── Task_6 │ │ └── Task_6.cpp │ ├── Task_7 │ │ ├── Task_7.cpp │ │ └── test_runner.h │ ├── Task_8 │ │ ├── Deque.h │ │ ├── Task_8.cpp │ │ ├── test_runner.h │ │ ├── tests.cpp │ │ └── tests.h │ └── Task_9 │ │ ├── Task_9.cpp │ │ ├── iterator_range.h │ │ ├── paginator.h │ │ ├── test_runner.h │ │ ├── tests.cpp │ │ └── tests.h ├── Week_2 │ ├── Readme.md │ ├── Task_1 │ │ ├── Task_1.cpp │ │ ├── profiler.h │ │ ├── student.h │ │ └── test_runner.h │ ├── Task_2 │ │ ├── Task_2.cpp │ │ ├── learner.cpp │ │ ├── learner.h │ │ └── profiler.h │ ├── Task_3 │ │ ├── Task_3.cpp │ │ └── slow.cpp │ ├── Task_4 │ │ ├── Task_4.cpp │ │ └── slow.cpp │ └── Task_5 │ │ └── Task_5.cpp ├── Week_3 │ ├── Readme.md │ ├── Task_1 │ │ ├── Task_1.cpp │ │ └── test_runner.h │ ├── Task_2 │ │ ├── Task_2.cpp │ │ └── test_runner.h │ ├── Task_3 │ │ ├── Task_3.cpp │ │ ├── simple_vector.h │ │ └── test_runner.h │ └── Task_4 │ │ ├── Task_4.cpp │ │ └── test_runner.h ├── Week_4 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_2 │ │ ├── Task_2.cpp │ │ ├── profiler.h │ │ ├── stack_vector.h │ │ └── test_runner.h │ ├── Task_3 │ │ ├── Task_3.cpp │ │ └── test_runner.h │ ├── Task_4 │ │ ├── Task_4.cpp │ │ ├── profiler.h │ │ └── test_runner.h │ ├── Task_5 │ │ ├── Task_5.cpp │ │ ├── profiler.h │ │ └── test_runner.h │ └── Task_6 │ │ ├── Task_6.cpp │ │ ├── http_request.h │ │ ├── profiler.h │ │ ├── stats.cpp │ │ ├── stats.h │ │ └── test_runner.h └── Week_5 │ ├── Readme.md │ ├── Task_1 │ ├── Task_1.cpp │ └── test_runner.h │ ├── Task_10 │ ├── Task_10.cpp │ ├── profile.h │ └── test_runner.h │ ├── Task_11 │ ├── Task_11.cpp │ ├── profile.h │ └── test_runner.h │ ├── Task_2 │ ├── Task_2.cpp │ └── test_runner.h │ ├── Task_3 │ ├── Task_3.cpp │ ├── simple_vector.h │ └── test_runner.h │ ├── Task_4 │ ├── Task_4.cpp │ └── test_runner.h │ ├── Task_5 │ ├── Task_5.cpp │ ├── simple_vector_2.h │ └── test_runner.h │ ├── Task_6 │ ├── Task_6.cpp │ └── test_runner.h │ ├── Task_7 │ ├── Task_7.cpp │ └── test_runner.h │ ├── Task_8 │ ├── Task_8.cpp │ └── test_runner.h │ └── Task_9 │ ├── Task_9.cpp │ ├── profile.h │ └── test_runner.h ├── White Belt ├── Readme.md ├── Week_1 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_2 │ │ └── Task_2.cpp │ ├── Task_3 │ │ └── Task_3.cpp │ ├── Task_4 │ │ └── Task_4.cpp │ ├── Task_5 │ │ └── Task_5.cpp │ ├── Task_6 │ │ └── Task_6.cpp │ ├── Task_7 │ │ └── Task_7.cpp │ ├── Task_8 │ │ └── Task_8.cpp │ ├── Task_9 │ │ └── Task_9.cpp │ └── Updated │ │ ├── Task_2.cpp │ │ ├── Task_5.cpp │ │ └── Task_9.cpp ├── Week_2 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_10 │ │ └── Task_10.cpp │ ├── Task_11 │ │ └── Task_11.cpp │ ├── Task_12 │ │ └── Task_12.cpp │ ├── Task_13 │ │ └── Task_13.cpp │ ├── Task_14 │ │ └── Task_14.cpp │ ├── Task_15 │ │ └── Task_15.cpp │ ├── Task_16 │ │ └── Task_16.cpp │ ├── Task_17 │ │ └── Task_17.cpp │ ├── Task_18 │ │ └── Task_18.cpp │ ├── Task_2 │ │ └── Task_2.cpp │ ├── Task_3 │ │ └── Task_3.cpp │ ├── Task_4 │ │ └── Task_4.cpp │ ├── Task_5 │ │ └── Task_5.cpp │ ├── Task_6 │ │ └── Task_6.cpp │ ├── Task_7 │ │ └── Task_7.cpp │ ├── Task_8 │ │ └── Task_8.cpp │ ├── Task_9 │ │ └── Task_9.cpp │ └── Updated │ │ ├── Task_10.cpp │ │ ├── Task_12.cpp │ │ ├── Task_13.cpp │ │ ├── Task_2.cpp │ │ ├── Task_3.cpp │ │ ├── Task_5.cpp │ │ ├── Task_6.cpp │ │ ├── Task_7.cpp │ │ └── Task_9.cpp ├── Week_3 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_2 │ │ └── Task_2.cpp │ ├── Task_3 │ │ └── Task_3.cpp │ ├── Task_4 │ │ └── Task_4.cpp │ ├── Task_5 │ │ └── Task_5.cpp │ ├── Task_6 │ │ └── Task_6.cpp │ ├── Task_7 │ │ └── Task_7.cpp │ └── Task_8 │ │ └── Task_8.cpp ├── Week_4 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_10 │ │ └── Task_10.cpp │ ├── Task_11 │ │ └── Task_11.cpp │ ├── Task_12 │ │ └── Task_12.cpp │ ├── Task_13 │ │ └── Task_13.cpp │ ├── Task_14 │ │ └── Task_14.cpp │ ├── Task_15 │ │ └── Task_15.cpp │ ├── Task_16 │ │ └── Task_16.cpp │ ├── Task_17 │ │ └── Task_17.cpp │ ├── Task_2 │ │ └── Task_2.cpp │ ├── Task_3 │ │ └── Task_3.cpp │ ├── Task_4 │ │ ├── Task_4.cpp │ │ └── input.txt │ ├── Task_5 │ │ ├── Task_5.cpp │ │ ├── input.txt │ │ └── output.txt │ ├── Task_6 │ │ ├── Task_6.cpp │ │ └── input.txt │ ├── Task_7 │ │ ├── Task_7.cpp │ │ └── input.txt │ ├── Task_8 │ │ └── Task_8.cpp │ └── Task_9 │ │ └── Task_9.cpp └── Week_5 (Final_project) │ ├── Readme.md │ ├── Updated │ ├── Database.cpp │ ├── Database.h │ ├── Date.cpp │ ├── Date.h │ └── main.cpp │ └── Week_5 (Final_project).cpp ├── Yellow Belt ├── Readme.md ├── Week_1 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_2 │ │ └── Task_2.cpp │ ├── Task_3 │ │ └── Task_3.cpp │ ├── Task_4 │ │ └── Task_4.cpp │ ├── Task_5 │ │ └── Task_5.cpp │ ├── Task_6 │ │ └── Task_6.cpp │ └── Task_7 │ │ └── Task_7.cpp ├── Week_2 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_2 │ │ └── Task_2.cpp │ ├── Task_3 │ │ └── Task_3.cpp │ ├── Task_4 │ │ └── Task_4.cpp │ └── Task_5 │ │ └── Task_5.cpp ├── Week_3 │ ├── Readme.md │ ├── Task_1 │ │ ├── Task_1.cpp │ │ ├── Test_runner.cpp │ │ ├── Test_runner.h │ │ ├── sum_reverse_sort.cpp │ │ └── sum_reverse_sort.h │ ├── Task_2 │ │ ├── Task_2.cpp │ │ ├── UnitFramework.cpp │ │ ├── UnitFramework.h │ │ ├── UnitTests.cpp │ │ ├── UnitTests.h │ │ ├── phone_number.cpp │ │ └── phone_number.h │ ├── Task_3 │ │ ├── Rectangle.cpp │ │ ├── Rectangle.h │ │ └── Task_3.cpp │ └── Task_4 │ │ ├── Task_4.cpp │ │ ├── bus_manager.cpp │ │ ├── bus_manager.h │ │ ├── query.cpp │ │ ├── query.h │ │ ├── responses.cpp │ │ └── responses.h ├── Week_4 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_10 │ │ ├── FindStartsWithChar.h │ │ ├── FindStartsWithPrefix.cpp │ │ ├── FindStartsWithPrefix.h │ │ └── Task_10.cpp │ ├── Task_11 │ │ └── Task_11.cpp │ ├── Task_2 │ │ ├── FindGreaterElements.h │ │ └── Task_2.cpp │ ├── Task_3 │ │ └── Task_3.cpp │ ├── Task_4 │ │ ├── RemoveDuplicates.h │ │ └── Task_4.cpp │ ├── Task_5 │ │ └── Task_5.cpp │ ├── Task_6 │ │ ├── ComputeMedianAge.h │ │ ├── Person.cpp │ │ ├── Person.h │ │ └── Task_6.cpp │ ├── Task_7 │ │ ├── MergeSort.h │ │ ├── MergeSort_Div3.h │ │ └── Task_7.cpp │ ├── Task_8 │ │ └── Task_8.cpp │ └── Task_9 │ │ ├── Person.cpp │ │ ├── Person.h │ │ └── Task_9.cpp ├── Week_5 │ ├── Readme.md │ ├── Task_1 │ │ └── Task_1.cpp │ ├── Task_2 │ │ └── Task_2.cpp │ ├── Task_3 │ │ ├── Circle.cpp │ │ ├── Circle.h │ │ ├── Figure.h │ │ ├── Rect.cpp │ │ ├── Rect.h │ │ ├── Task_3.cpp │ │ ├── Triangle.cpp │ │ └── Triangle.h │ └── Task_4 │ │ ├── Task_4.cpp │ │ └── original_code.cpp └── Week_6 (Final_project) │ ├── Readme.md │ ├── condition_parser.cpp │ ├── condition_parser.h │ ├── condition_parser_test.cpp │ ├── database.cpp │ ├── database.h │ ├── date.cpp │ ├── date.h │ ├── main.cpp │ ├── node.cpp │ ├── node.h │ ├── test_runner.cpp │ ├── test_runner.h │ ├── token.cpp │ └── token.h └── logo.jpg /Brown Belt/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # C++: коричневый пояс 3 | 4 | [Основы разработки на C++: коричневый пояс](https://www.coursera.org/learn/c-plus-plus-brown) by Moscow Institute of Physics and Technology & Yandex 5 | 6 | ## Об этом курсе 7 | 8 | ЭОсновная цель этого курса — научить идиомам языка C++, то есть показать, как с помощью различных возможностей языка создавать элегантные, эффективные и надёжные блоки кода. В совокупности со знаниями, полученными на «Красном поясе», это позволит вам создавать не только быстрые и легко поддерживаемые программы. 9 | 10 | Кроме того, будут освещены темы, которые не поместились в объём предыдущих курсов: пространства имён и эффективное использование ассоциативных контейнеров. 11 | 12 | ## Программа курса 13 | 14 | ### [1. Эффективное использование ассоциативных контейнеров](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/Brown%20Belt/Week_1) 15 | 16 | ### [2. Пространства имён и указатель this](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/Brown%20Belt/Week_2) 17 | 18 | ### [3. Константность и unique_ptr]() 19 | 20 | ### [4. shared_ptr и RAII]() 21 | 22 | ### [5. Функции: принципы понятного кода]() 23 | 24 | ### [6. Финальная задача]( ) 25 | -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_1/xml.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class Node 11 | { 12 | public: 13 | Node(std::string name, std::unordered_map attrs); 14 | 15 | const std::vector& Children() const; 16 | void AddChild(Node node); 17 | std::string_view Name() const; 18 | 19 | template 20 | T AttributeValue(const std::string& name) const; 21 | 22 | private: 23 | std::string name; 24 | std::vector children; 25 | std::unordered_map attrs; 26 | }; 27 | 28 | class Document 29 | { 30 | public: 31 | explicit Document(Node root); 32 | 33 | const Node& GetRoot() const; 34 | 35 | private: 36 | Node root; 37 | }; 38 | 39 | Document Load(std::istream& input); 40 | 41 | template 42 | inline T Node::AttributeValue(const std::string& name) const 43 | { 44 | std::istringstream attr_input(attrs.at(name)); 45 | T result; 46 | attr_input >> result; 47 | return result; 48 | } -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_2/json.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Node 10 | { 11 | public: 12 | explicit Node(std::vector array); 13 | explicit Node(std::map map); 14 | explicit Node(int value); 15 | explicit Node(std::string value); 16 | 17 | const std::vector& AsArray() const; 18 | const std::map& AsMap() const; 19 | int AsInt() const; 20 | const std::string& AsString() const; 21 | 22 | private: 23 | std::vector as_array; 24 | std::map as_map; 25 | int as_int; 26 | std::string as_string; 27 | }; 28 | 29 | class Document 30 | { 31 | public: 32 | explicit Document(Node root); 33 | 34 | const Node& GetRoot() const; 35 | 36 | private: 37 | Node root; 38 | }; 39 | 40 | Document Load(std::istream& input); -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_3/ini.cpp: -------------------------------------------------------------------------------- 1 | #include "ini.h" 2 | 3 | #include 4 | #include 5 | 6 | namespace Ini 7 | { 8 | Section& Document::AddSection(std::string name) 9 | { 10 | return sections[std::move(name)]; 11 | } 12 | 13 | const Section& Document::GetSection(const std::string& name) const 14 | { 15 | return sections.at(name); 16 | } 17 | 18 | size_t Document::SectionCount() const 19 | { 20 | return sections.size(); 21 | } 22 | 23 | std::string_view FindSectionName(std::string_view line) 24 | { 25 | line.remove_prefix(1); 26 | 27 | size_t pos = line.find(']'); 28 | 29 | line.remove_suffix(line.size() - pos); 30 | 31 | return line; 32 | } 33 | 34 | std::pair FindSection(std::string_view line) 35 | { 36 | size_t pos = line.find('='); 37 | 38 | std::string_view category = line.substr(0, pos); 39 | 40 | std::string_view amount = line.substr(pos + 1); 41 | 42 | return { category, amount }; 43 | } 44 | 45 | Document Load(std::istream& input) 46 | { 47 | Document result; 48 | Section* section = nullptr; 49 | 50 | for (std::string line; std::getline(input, line); ) 51 | { 52 | if (line[0] == '[') 53 | { 54 | std::string_view name = FindSectionName(line); 55 | section = &result.AddSection(std::string(name)); 56 | } 57 | else if (!line.empty()) 58 | { 59 | auto [category, amount] = FindSection(line); 60 | section->insert({ std::string(category), std::string(amount) }); 61 | } 62 | } 63 | 64 | return result; 65 | } 66 | } -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_3/ini.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Ini 8 | { 9 | using Section = std::unordered_map; 10 | 11 | class Document 12 | { 13 | public: 14 | Document() = default; 15 | Section& AddSection(std::string name); 16 | const Section& GetSection(const std::string& name) const; 17 | size_t SectionCount() const; 18 | 19 | private: 20 | std::unordered_map sections; 21 | }; 22 | 23 | std::string_view FindSectionName(std::string_view line); 24 | std::pair FindSection(std::string_view line); 25 | 26 | Document Load(std::istream& input); 27 | } -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_4/json.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Json 10 | { 11 | 12 | class Node 13 | { 14 | public: 15 | explicit Node(std::vector array); 16 | explicit Node(std::map map); 17 | explicit Node(int value); 18 | explicit Node(std::string value); 19 | 20 | const std::vector& AsArray() const; 21 | const std::map& AsMap() const; 22 | int AsInt() const; 23 | const std::string& AsString() const; 24 | 25 | private: 26 | std::vector as_array; 27 | std::map as_map; 28 | int as_int; 29 | std::string as_string; 30 | }; 31 | 32 | class Document 33 | { 34 | public: 35 | explicit Document(Node root); 36 | 37 | const Node& GetRoot() const; 38 | 39 | private: 40 | Node root; 41 | }; 42 | 43 | Document Load(std::istream& input); 44 | } -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_4/xml.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Xml 11 | { 12 | 13 | class Node 14 | { 15 | public: 16 | Node(std::string name, std::unordered_map attrs); 17 | 18 | const std::vector& Children() const; 19 | void AddChild(Node node); 20 | std::string_view Name() const; 21 | 22 | template 23 | T AttributeValue(const std::string& name) const; 24 | 25 | private: 26 | std::string name; 27 | std::vector children; 28 | std::unordered_map attrs; 29 | }; 30 | 31 | class Document 32 | { 33 | public: 34 | explicit Document(Node root); 35 | 36 | const Node& GetRoot() const; 37 | 38 | private: 39 | Node root; 40 | }; 41 | 42 | Document Load(std::istream& input); 43 | 44 | template 45 | inline T Node::AttributeValue(const std::string& name) const 46 | { 47 | std::istringstream attr_input(attrs.at(name)); 48 | T result; 49 | attr_input >> result; 50 | return result; 51 | } 52 | } -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_5/Task_5.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Brown Belt/Week_2/Task_5/Task_5.cpp -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_5/stats_aggregator.cpp: -------------------------------------------------------------------------------- 1 | #include "stats_aggregator.h" 2 | 3 | namespace StatsAggregators 4 | { 5 | template 6 | std::ostream& operator<< (std::ostream& os, const std::optional& v) 7 | { 8 | if (v) 9 | { 10 | os << *v; 11 | } 12 | else 13 | { 14 | os << "undefined"; 15 | } 16 | return os; 17 | } 18 | 19 | void Composite::Process(int value) 20 | { 21 | for (auto& aggr : aggregators) 22 | { 23 | aggr->Process(value); 24 | } 25 | } 26 | 27 | void Composite::PrintValue(std::ostream& output) const 28 | { 29 | for (const auto& aggr : aggregators) 30 | { 31 | aggr->PrintValue(output); 32 | output << '\n'; 33 | } 34 | } 35 | 36 | void Composite::Add(std::unique_ptr aggr) 37 | { 38 | aggregators.push_back(std::move(aggr)); 39 | } 40 | 41 | void Sum::Process(int value) 42 | { 43 | sum += value; 44 | } 45 | 46 | void Sum::PrintValue(std::ostream& out) const 47 | { 48 | out << "Sum is " << sum; 49 | } 50 | 51 | void Min::Process(int value) 52 | { 53 | if (!current_min || value < *current_min) 54 | { 55 | current_min = value; 56 | } 57 | } 58 | 59 | void Min::PrintValue(std::ostream& out) const 60 | { 61 | out << "Min is " << current_min; 62 | } 63 | 64 | void Max::Process(int value) 65 | { 66 | if (!current_max || value > * current_max) 67 | { 68 | current_max = value; 69 | } 70 | } 71 | 72 | void Max::PrintValue(std::ostream& out) const 73 | { 74 | out << "Max is " << current_max; 75 | } 76 | 77 | void Average::Process(int value) 78 | { 79 | sum += value; 80 | ++total; 81 | } 82 | 83 | void Average::PrintValue(std::ostream& out) const 84 | { 85 | out << "Average is "; 86 | if (total == 0) 87 | { 88 | out << "undefined"; 89 | } 90 | else 91 | { 92 | out << sum / total; 93 | } 94 | } 95 | 96 | void Mode::Process(int value) 97 | { 98 | int current_count = ++count[value]; 99 | if (!mode || current_count > count[*mode]) 100 | { 101 | mode = value; 102 | } 103 | } 104 | 105 | void Mode::PrintValue(std::ostream& out) const 106 | { 107 | out << "Mode is " << mode; 108 | } 109 | } -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_5/stats_aggregator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | struct StatsAggregator 11 | { 12 | virtual ~StatsAggregator() 13 | { 14 | } 15 | 16 | virtual void Process(int value) = 0; 17 | virtual void PrintValue(std::ostream& out) const = 0; 18 | }; 19 | 20 | namespace StatsAggregators 21 | { 22 | 23 | class Sum : public StatsAggregator 24 | { 25 | public: 26 | void Process(int value) override; 27 | void PrintValue(std::ostream& out) const override; 28 | 29 | private: 30 | int sum = 0; 31 | }; 32 | 33 | class Min : public StatsAggregator 34 | { 35 | public: 36 | void Process(int value) override; 37 | void PrintValue(std::ostream& out) const override; 38 | 39 | private: 40 | // Ранее мы не рассматривали шаблон std::optional. О нём можно почитать в документации 41 | // https://en.cppreference.com/w/cpp/utility/optional. Кроме того, ему будет уделено внимание 42 | // в разделе про функции 43 | std::optional current_min; 44 | }; 45 | 46 | class Max : public StatsAggregator 47 | { 48 | public: 49 | void Process(int value) override; 50 | void PrintValue(std::ostream& out) const override; 51 | 52 | private: 53 | std::optional current_max; 54 | }; 55 | 56 | class Average : public StatsAggregator 57 | { 58 | public: 59 | void Process(int value) override; 60 | void PrintValue(std::ostream& out) const override; 61 | 62 | private: 63 | int sum = 0; 64 | int total = 0; 65 | }; 66 | 67 | class Mode : public StatsAggregator 68 | { 69 | public: 70 | void Process(int value) override; 71 | void PrintValue(std::ostream& out) const override; 72 | 73 | private: 74 | std::unordered_map count; 75 | std::optional mode; 76 | }; 77 | 78 | class Composite : public StatsAggregator 79 | { 80 | public: 81 | void Process(int value) override; 82 | void PrintValue(std::ostream& output) const override; 83 | 84 | void Add(std::unique_ptr aggr); 85 | 86 | private: 87 | std::vector> aggregators; 88 | }; 89 | 90 | void TestSum(); 91 | void TestMin(); 92 | void TestMax(); 93 | void TestAverage(); 94 | void TestMode(); 95 | void TestComposite(); 96 | } -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_5/stats_aggregator_test.cpp: -------------------------------------------------------------------------------- 1 | #include "stats_aggregator.h" 2 | #include "test_runner.h" 3 | 4 | #include 5 | 6 | namespace StatsAggregators 7 | { 8 | std::string PrintedValue(const StatsAggregator& aggr) 9 | { 10 | std::ostringstream output; 11 | aggr.PrintValue(output); 12 | return output.str(); 13 | } 14 | 15 | void TestSum() 16 | { 17 | Sum aggr; 18 | ASSERT_EQUAL(PrintedValue(aggr), "Sum is 0"); 19 | 20 | aggr.Process(3); 21 | aggr.Process(8); 22 | aggr.Process(-1); 23 | aggr.Process(16); 24 | 25 | ASSERT_EQUAL(PrintedValue(aggr), "Sum is 26"); 26 | } 27 | 28 | void TestMin() 29 | { 30 | Min aggr; 31 | ASSERT_EQUAL(PrintedValue(aggr), "Min is undefined"); 32 | 33 | aggr.Process(3); 34 | aggr.Process(8); 35 | aggr.Process(-1); 36 | aggr.Process(16); 37 | 38 | ASSERT_EQUAL(PrintedValue(aggr), "Min is -1"); 39 | } 40 | 41 | void TestMax() 42 | { 43 | Max aggr; 44 | ASSERT_EQUAL(PrintedValue(aggr), "Max is undefined"); 45 | 46 | aggr.Process(3); 47 | aggr.Process(8); 48 | aggr.Process(-1); 49 | aggr.Process(16); 50 | 51 | ASSERT_EQUAL(PrintedValue(aggr), "Max is 16"); 52 | } 53 | 54 | void TestAverage() 55 | { 56 | Average aggr; 57 | ASSERT_EQUAL(PrintedValue(aggr), "Average is undefined"); 58 | 59 | aggr.Process(3); 60 | aggr.Process(8); 61 | aggr.Process(-1); 62 | aggr.Process(16); 63 | 64 | ASSERT_EQUAL(PrintedValue(aggr), "Average is 6"); 65 | } 66 | 67 | void TestMode() 68 | { 69 | Mode aggr; 70 | ASSERT_EQUAL(PrintedValue(aggr), "Mode is undefined"); 71 | 72 | aggr.Process(3); 73 | aggr.Process(3); 74 | aggr.Process(8); 75 | aggr.Process(8); 76 | aggr.Process(8); 77 | aggr.Process(8); 78 | aggr.Process(-1); 79 | aggr.Process(-1); 80 | aggr.Process(-1); 81 | aggr.Process(16); 82 | 83 | ASSERT_EQUAL(PrintedValue(aggr), "Mode is 8"); 84 | } 85 | 86 | void TestComposite() 87 | { 88 | Composite aggr; 89 | aggr.Add(std::make_unique()); 90 | aggr.Add(std::make_unique()); 91 | aggr.Add(std::make_unique()); 92 | aggr.Add(std::make_unique()); 93 | aggr.Add(std::make_unique()); 94 | 95 | aggr.Process(3); 96 | aggr.Process(8); 97 | aggr.Process(-1); 98 | aggr.Process(16); 99 | aggr.Process(16); 100 | 101 | std::string expected = "Sum is 42\n"; 102 | expected += "Min is -1\n"; 103 | expected += "Max is 16\n"; 104 | expected += "Average is 8\n"; 105 | expected += "Mode is 16\n"; 106 | ASSERT_EQUAL(PrintedValue(aggr), expected); 107 | } 108 | } -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_6/game_object.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Unit; 4 | class Building; 5 | class Tower; 6 | class Fence; 7 | 8 | struct GameObject 9 | { 10 | virtual ~GameObject() = default; 11 | 12 | virtual bool Collide(const GameObject& that) const = 0; 13 | virtual bool CollideWith(const Unit& that) const = 0; 14 | virtual bool CollideWith(const Building& that) const = 0; 15 | virtual bool CollideWith(const Tower& that) const = 0; 16 | virtual bool CollideWith(const Fence& that) const = 0; 17 | }; 18 | 19 | bool Collide(const GameObject& first, const GameObject& second); 20 | -------------------------------------------------------------------------------- /Brown Belt/Week_2/Task_6/geo2d.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace geo2d 6 | { 7 | 8 | struct Point 9 | { 10 | int x, y; 11 | }; 12 | 13 | uint64_t DistanceSquared(Point p1, Point p2); 14 | 15 | struct Vector 16 | { 17 | int x, y; 18 | 19 | Vector(int xx, int yy) 20 | : x(xx) 21 | , y(yy) 22 | { 23 | } 24 | 25 | Vector(Point from, Point to) 26 | : x(to.x - from.x) 27 | , y(to.y - from.y) 28 | { 29 | } 30 | }; 31 | 32 | int64_t operator * (Vector lhs, Vector rhs); 33 | int64_t ScalarProduct(Vector lhs, Vector rhs); 34 | 35 | struct Segment 36 | { 37 | Point p1, p2; 38 | }; 39 | 40 | class Rectangle 41 | { 42 | private: 43 | int x_left, x_right; 44 | int y_bottom, y_top; 45 | 46 | public: 47 | Rectangle(Point p1, Point p2); 48 | 49 | int Left() const { return x_left; } 50 | int Right() const { return x_right; } 51 | int Top() const { return y_top; } 52 | int Bottom() const { return y_bottom; } 53 | 54 | Point BottomLeft() const { return { x_left, y_bottom }; } 55 | Point BottomRight() const { return { x_right, y_bottom }; } 56 | Point TopRight() const { return { x_right, y_top }; } 57 | Point TopLeft() const { return { x_left, y_top }; } 58 | }; 59 | 60 | struct Circle 61 | { 62 | Point center; 63 | uint32_t radius; 64 | }; 65 | 66 | bool Collide(Point p, Point q); 67 | bool Collide(Point p, Segment s); 68 | bool Collide(Point p, Rectangle r); 69 | bool Collide(Point p, Circle c); 70 | bool Collide(Rectangle r, Point p); 71 | bool Collide(Rectangle r, Segment s); 72 | bool Collide(Rectangle r1, Rectangle r2); 73 | bool Collide(Rectangle r, Circle c); 74 | bool Collide(Segment s, Point p); 75 | bool Collide(Segment s1, Segment s2); 76 | bool Collide(Segment s, Rectangle r); 77 | bool Collide(Segment s, Circle c); 78 | bool Collide(Circle c, Point p); 79 | bool Collide(Circle c, Rectangle r); 80 | bool Collide(Circle c, Segment s); 81 | bool Collide(Circle c1, Circle c2); 82 | } 83 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Brown Belt/Week_3/Task_1/Task_1.cpp -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_1/Task_1.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Исходные файлы 20 | 21 | 22 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_1/Task_1.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Brown Belt/Week_3/Task_2/Task_2.cpp -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_2/Task_2.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Исходные файлы 20 | 21 | 22 | 23 | 24 | Файлы заголовков 25 | 26 | 27 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_2/Task_2.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_3/Task_3.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Исходные файлы 20 | 21 | 22 | 23 | 24 | Файлы заголовков 25 | 26 | 27 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_3/Task_3.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_6/Task_6.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Исходные файлы 20 | 21 | 22 | 23 | 24 | Файлы заголовков 25 | 26 | 27 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_6/Task_6.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_7/Task_7.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Исходные файлы 20 | 21 | 22 | 23 | 24 | Файлы заголовков 25 | 26 | 27 | Файлы заголовков 28 | 29 | 30 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_7/Task_7.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Brown Belt/Week_3/Task_7/animals.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Animal 4 | { 5 | public: 6 | virtual std::string Voice() const 7 | { 8 | return "Not implemented yet"; 9 | } 10 | virtual ~Animal() 11 | { 12 | } 13 | }; 14 | 15 | 16 | class Tiger : public Animal 17 | { 18 | std::string Voice() const override 19 | { 20 | return "Rrrr"; 21 | } 22 | }; 23 | 24 | 25 | class Wolf : public Animal 26 | { 27 | std::string Voice() const override 28 | { 29 | return "Wooo"; 30 | } 31 | }; 32 | 33 | 34 | class Fox : public Animal 35 | { 36 | std::string Voice() const override 37 | { 38 | return "Tyaf"; 39 | } 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /Red Belt/Readme.md: -------------------------------------------------------------------------------- 1 | # C++: красный пояс 2 | 3 | [Основы разработки на C++: красный пояс](https://www.coursera.org/learn/c-plus-plus-red) by Moscow Institute of Physics and Technology & Yandex 4 | 5 | ## Об этом курсе 6 | 7 | Этот курс является продолжением курса "Основы разработки на C++: жёлтый пояс". Основная цель курса — научить писать на С++ эффективный код. Кроме того рассмотрены некоторые возможности С++, которые не попали в предыдущие курсы. 8 | 9 | В курсе рассмотрены: 10 | - макросы 11 | - шаблоны классов 12 | - принципы оптимизации кода 13 | - эффективное использование потоков ввода/вывода 14 | - оценки сложности алгоритмов 15 | - модель памяти в С++ 16 | - эффективное использование линейных контейнеров (vector, deque, list, string) 17 | - move-семантика 18 | - введение в многопоточное программирование 19 | 20 | Кроме того, в курсе продемонстрировано, как, пользуясь знаниями только "Белого", "Жёлтого" и "Красного" поясов, разработать свой собственный профайлер. 21 | 22 | Так же, как и в предыдущих курсах, в конце вас ждёт финальный проект. Было бы странно в курсе от Яндекса не попросить вас создать свою поисковую систему! Именно этим вам и предстоит заняться в финальной задаче. 23 | 24 | ## Программа курса 25 | 26 | ### [1. Макросы и шаблоны классов](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/Red%20Belt/Week_1) 27 | 28 | ### [2. Принципы оптимизации кода, сложность алгоритмов и эффективное использование ввода/вывода](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/Red%20Belt/Week_2) 29 | 30 | ### [3. Модель памяти в C++](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/Red%20Belt/Week_3) 31 | 32 | ### [4. Эффективное использование линейных контейнеров](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/Red%20Belt/Week_4) 33 | 34 | ### [5. Move-семантика и базовая многопоточность](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/Red%20Belt/Week_5) 35 | 36 | ### [6. Финальная задача]( ) 37 | -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_1/Test_runner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | template 14 | ostream& operator << (ostream& os, const vector& s) { 15 | os << "{"; 16 | bool first = true; 17 | for (const auto& x : s) { 18 | if (!first) { 19 | os << ", "; 20 | } 21 | first = false; 22 | os << x; 23 | } 24 | return os << "}"; 25 | } 26 | 27 | template 28 | ostream& operator << (ostream& os, const set& s) { 29 | os << "{"; 30 | bool first = true; 31 | for (const auto& x : s) { 32 | if (!first) { 33 | os << ", "; 34 | } 35 | first = false; 36 | os << x; 37 | } 38 | return os << "}"; 39 | } 40 | 41 | template 42 | ostream& operator << (ostream& os, const map& m) { 43 | os << "{"; 44 | bool first = true; 45 | for (const auto& kv : m) { 46 | if (!first) { 47 | os << ", "; 48 | } 49 | first = false; 50 | os << kv.first << ": " << kv.second; 51 | } 52 | return os << "}"; 53 | } 54 | 55 | template 56 | void AssertEqual(const T& t, const U& u, const string& hint = {}) { 57 | if (!(t == u)) { 58 | ostringstream os; 59 | os << "Assertion failed: " << t << " != " << u; 60 | if (!hint.empty()) { 61 | os << " hint: " << hint; 62 | } 63 | throw runtime_error(os.str()); 64 | } 65 | } 66 | 67 | inline void Assert(bool b, const string& hint) { 68 | AssertEqual(b, true, hint); 69 | } 70 | 71 | class TestRunner { 72 | public: 73 | template 74 | void RunTest(TestFunc func, const string& test_name) { 75 | try { 76 | func(); 77 | cerr << test_name << " OK" << endl; 78 | } catch (exception& e) { 79 | ++fail_count; 80 | cerr << test_name << " fail: " << e.what() << endl; 81 | } catch (...) { 82 | ++fail_count; 83 | cerr << "Unknown exception caught" << endl; 84 | } 85 | } 86 | 87 | ~TestRunner() { 88 | if (fail_count > 0) { 89 | cerr << fail_count << " unit tests failed. Terminate" << endl; 90 | exit(1); 91 | } 92 | } 93 | 94 | private: 95 | int fail_count = 0; 96 | }; 97 | 98 | -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Давайте представим, что вы разрабатываете инновационный сервис поиска авиабилетов AviaScanner. 3 | 4 | В данный момент вы работаете над функцией сортировки результатов поиска. 5 | Пользователь вводит свой запрос и получает список подходящих билетов. 6 | Дальше он может задавать параметры сортировки этого списка. 7 | Например, сначала по цене, затем по времени вылета и, наконец, по аэропорту прилёта. 8 | 9 | Напишите макрос SORT_BY, который принимает в качестве параметра имя поля структуры AirlineTicket. 10 | Вызов sort(begin(tixs), end(tixs), SORT_BY(some_field)) должен приводить к сортировке вектора tixs по полю some_field. 11 | 12 | Вам дан файл airline_ticket.h, содержащий объявления структур Time, Date и AirlineTicket, 13 | а также заготовка решения в виде cpp-файла sort_by.cpp. 14 | 15 | Пришлите на проверку cpp-файл, который 16 | * подключает заголовочный файл airline_ticket.h 17 | * содержит макрос SORT_BY 18 | * содержит определения операторов, необходимых для использования классов Date и 19 | Time в алгоритме сортировки и макросе ASSERT_EQUAL (формат вывода в поток можете выбрать произвольный) 20 | */ 21 | 22 | #include "airline_ticket.h" 23 | #include "test_runner.h" 24 | 25 | #include 26 | #include 27 | 28 | using namespace std; 29 | 30 | #define SORT_BY(field) \ 31 | [](const AirlineTicket& lhs, const AirlineTicket& rhs) \ 32 | { \ 33 | return lhs.field < rhs.field; \ 34 | } 35 | 36 | 37 | void TestSortBy() 38 | { 39 | vector tixs = 40 | { 41 | {"VKO", "AER", "Utair", {2018, 2, 28}, {17, 40}, {2018, 2, 28}, {20, 0}, 1200}, 42 | {"AER", "VKO", "Utair", {2018, 3, 5}, {14, 15}, {2018, 3, 5}, {16, 30}, 1700}, 43 | {"AER", "SVO", "Aeroflot", {2018, 3, 5}, {18, 30}, {2018, 3, 5}, {20, 30}, 2300}, 44 | {"PMI", "DME", "Iberia", {2018, 2, 8}, {23, 00}, {2018, 2, 9}, { 3, 30}, 9000}, 45 | {"CDG", "SVO", "AirFrance", {2018, 3, 1}, {13, 00}, {2018, 3, 1}, {17, 30}, 8000}, 46 | }; 47 | 48 | sort(begin(tixs), end(tixs), SORT_BY(price)); 49 | ASSERT_EQUAL(tixs.front().price, 1200); 50 | ASSERT_EQUAL(tixs.back().price, 9000); 51 | 52 | sort(begin(tixs), end(tixs), SORT_BY(from)); 53 | ASSERT_EQUAL(tixs.front().from, "AER"); 54 | ASSERT_EQUAL(tixs.back().from, "VKO"); 55 | 56 | sort(begin(tixs), end(tixs), SORT_BY(arrival_date)); 57 | ASSERT_EQUAL(tixs.front().arrival_date, (Date{ 2018, 2, 9 })); 58 | ASSERT_EQUAL(tixs.back().arrival_date, (Date{ 2018, 3, 5 })); 59 | } 60 | 61 | int main() 62 | { 63 | TestRunner tr; 64 | RUN_TEST(tr, TestSortBy); 65 | } 66 | -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_3/airline_ticket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | struct Date 10 | { 11 | int year, month, day; 12 | }; 13 | 14 | struct Time 15 | { 16 | int hours, minutes; 17 | }; 18 | 19 | struct AirlineTicket 20 | { 21 | string from; 22 | string to; 23 | string airline; 24 | Date departure_date; 25 | Time departure_time; 26 | Date arrival_date; 27 | Time arrival_time; 28 | int price; 29 | }; 30 | 31 | bool operator< (const Date& lhs, const Date& rhs) 32 | { 33 | return std::tie(lhs.year, lhs.month, lhs.day) < std::tie(rhs.year, rhs.month, rhs.day); 34 | } 35 | 36 | bool operator== (const Date& lhs, const Date& rhs) 37 | { 38 | return std::tie(lhs.year, lhs.month, lhs.day) == std::tie(rhs.year, rhs.month, rhs.day); 39 | } 40 | 41 | std::ostream& operator<< (std::ostream& os, const Date& date) 42 | { 43 | return os << date.year << ", " << date.month << ", " << date.day; 44 | } 45 | 46 | 47 | bool operator< (const Time& lhs, const Time& rhs) 48 | { 49 | return std::tie(lhs.hours, lhs.minutes) < std::tie(rhs.hours, rhs.minutes); 50 | } 51 | 52 | bool operator== (const Time& lhs, const Time& rhs) 53 | { 54 | return std::tie(lhs.hours, lhs.minutes) == std::tie(rhs.hours, rhs.minutes); 55 | } 56 | 57 | std::ostream& operator<< (std::ostream& os, const Time& time) 58 | { 59 | return os << time.hours << time.minutes; 60 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_4/Task_4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Продолжим работу над сервисом поиска авиабилетов AviaScanner. 3 | Наш сервис хранит базу данных билетов в виде vector, 4 | где AirlineTicket — такая же структура, как и в предыдущей задаче. 5 | Периодически наш сервис обходит сайты авиакомпаний, собирает свежую информацию о доступных билетах и обновляет записи в своей базе данных. 6 | Делается это с помощью функции void UpdateTicket(AirlineTicket& ticket, const map& updates). 7 | Параметр updates содержит пары (имя поля; новое значение). 8 | При этом он содержит только те поля, которые поменялись. 9 | 10 | Напишите макрос UPDATE_FIELD. 11 | Вам дан файл airline_ticket.h, содержащий объявления структур Time, Date и AirlineTicket, 12 | а также заготовка решения в виде cpp-файла update_field.cpp. 13 | Пришлите на проверку cpp-файл, который 14 | * подключает заголовочный файл airline_ticket.h 15 | * содержит макрос UPDATE_FIELD 16 | * содержит определения операторов, необходимых для считывания классов Date и Time из потока istream 17 | и их использования в макросе ASSERT_EQUAL (формат ввода смотрите в юнит-тестах в файле update_field.cpp) 18 | */ 19 | 20 | #include "airline_ticket.h" 21 | #include "test_runner.h" 22 | 23 | using namespace std; 24 | 25 | #define UPDATE_FIELD(ticket, field, values) \ 26 | { \ 27 | auto it = values.find(#field); \ 28 | if (it != values.end()) \ 29 | { \ 30 | std::istringstream is (it->second); \ 31 | is >> ticket.field; \ 32 | } \ 33 | } 34 | 35 | void TestUpdate() 36 | { 37 | AirlineTicket t; 38 | t.price = 0; 39 | 40 | const map updates1 = 41 | { 42 | {"departure_date", "2018-2-28"}, 43 | {"departure_time", "17:40"}, 44 | }; 45 | UPDATE_FIELD(t, departure_date, updates1); 46 | UPDATE_FIELD(t, departure_time, updates1); 47 | UPDATE_FIELD(t, price, updates1); 48 | 49 | ASSERT_EQUAL(t.departure_date, (Date{ 2018, 2, 28 })); 50 | ASSERT_EQUAL(t.departure_time, (Time{ 17, 40 })); 51 | ASSERT_EQUAL(t.price, 0); 52 | 53 | const map updates2 = 54 | { 55 | {"price", "12550"}, 56 | {"arrival_time", "20:33"}, 57 | }; 58 | UPDATE_FIELD(t, departure_date, updates2); 59 | UPDATE_FIELD(t, departure_time, updates2); 60 | UPDATE_FIELD(t, arrival_time, updates2); 61 | UPDATE_FIELD(t, price, updates2); 62 | 63 | // updates2 не содержит ключей "departure_date" и "departure_time", поэтому 64 | // значения этих полей не должны измениться 65 | ASSERT_EQUAL(t.departure_date, (Date{ 2018, 2, 28 })); 66 | ASSERT_EQUAL(t.departure_time, (Time{ 17, 40 })); 67 | ASSERT_EQUAL(t.price, 12550); 68 | ASSERT_EQUAL(t.arrival_time, (Time{ 20, 33 })); 69 | } 70 | 71 | int main() 72 | { 73 | TestRunner tr; 74 | RUN_TEST(tr, TestUpdate); 75 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_4/airline_ticket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | struct Date 10 | { 11 | int year, month, day; 12 | }; 13 | 14 | struct Time 15 | { 16 | int hours, minutes; 17 | }; 18 | 19 | struct AirlineTicket 20 | { 21 | string from; 22 | string to; 23 | string airline; 24 | Date departure_date; 25 | Time departure_time; 26 | Date arrival_date; 27 | Time arrival_time; 28 | int price; 29 | }; 30 | 31 | bool operator< (const Date& lhs, const Date& rhs) 32 | { 33 | return std::tie(lhs.year, lhs.month, lhs.day) < std::tie(rhs.year, rhs.month, rhs.day); 34 | } 35 | 36 | bool operator== (const Date& lhs, const Date& rhs) 37 | { 38 | return std::tie(lhs.year, lhs.month, lhs.day) == std::tie(rhs.year, rhs.month, rhs.day); 39 | } 40 | 41 | std::ostream& operator<< (std::ostream& os, const Date& date) 42 | { 43 | return os << date.year << ", " << date.month << ", " << date.day; 44 | } 45 | 46 | std::istream& operator>> (std::istream& is, Date& date) 47 | { 48 | is >> date.year; 49 | is.ignore(1); 50 | is >> date.month; 51 | is.ignore(1); 52 | return is >> date.day; 53 | } 54 | 55 | bool operator< (const Time& lhs, const Time& rhs) 56 | { 57 | return std::tie(lhs.hours, lhs.minutes) < std::tie(rhs.hours, rhs.minutes); 58 | } 59 | 60 | bool operator== (const Time& lhs, const Time& rhs) 61 | { 62 | return std::tie(lhs.hours, lhs.minutes) == std::tie(rhs.hours, rhs.minutes); 63 | } 64 | 65 | std::ostream& operator<< (std::ostream& os, const Time& time) 66 | { 67 | return os << time.hours << time.minutes; 68 | } 69 | 70 | std::istream& operator>> (std::istream& is, Time& time) 71 | { 72 | is >> time.hours; 73 | is.ignore(1); 74 | return is >> time.minutes; 75 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_5/Task_5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Вам дан макрос, который распечатывает два переданных ему значения в переданный поток вывода. 3 | В реализации макроса есть недостаток, ограничивающий его применимость в реальных программах. 4 | Вам требуется найти и устранить недостаток. 5 | */ 6 | #include "test_runner.h" 7 | 8 | #include 9 | 10 | using namespace std; 11 | 12 | #define PRINT_VALUES(out, x, y) \ 13 | do \ 14 | { \ 15 | out << (x) << endl; \ 16 | out << (y) << endl; \ 17 | break; \ 18 | } while (true) 19 | 20 | int main() 21 | { 22 | TestRunner tr; 23 | tr.RunTest([] 24 | { 25 | ostringstream output; 26 | PRINT_VALUES(output, 5, "red belt"); 27 | ASSERT_EQUAL(output.str(), "5\nred belt\n"); 28 | }, "PRINT_VALUES usage example"); 29 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_6/Task_6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Разработать макрос UNIQ_ID, который будет формировать идентификатор, уникальный в пределах данного cpp-файла. 3 | */ 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | #define UNIQ_ID_IMPL_2(lineno) _a_local_var_##lineno 10 | #define UNIQ_ID_IMPL(lineno) UNIQ_ID_IMPL_2(lineno) 11 | #define UNIQ_ID UNIQ_ID_IMPL(__LINE__) 12 | 13 | int main() 14 | { 15 | int UNIQ_ID = 0; 16 | string UNIQ_ID = "hello"; 17 | vector UNIQ_ID = { "hello", "world" }; 18 | vector UNIQ_ID = { 1, 2, 3, 4 }; 19 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_8/Deque.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | template 7 | class Deque 8 | { 9 | public: 10 | Deque() = default; 11 | 12 | bool Empty() const 13 | { 14 | return front_.empty() && back_.empty(); 15 | } 16 | 17 | size_t Size() const 18 | { 19 | return front_.size() + back_.size(); 20 | } 21 | 22 | const T& operator[] (const size_t index) const 23 | { 24 | if (index < front_.size()) 25 | { 26 | return front_[Size() - 1 - index]; 27 | } 28 | 29 | return back_[index - front_.size()]; 30 | } 31 | 32 | T& operator[] (const size_t index) 33 | { 34 | if (index < front_.size()) 35 | { 36 | return front_[front_.size() - 1 - index]; 37 | } 38 | 39 | return back_[index - front_.size()]; 40 | } 41 | 42 | const T& At(const size_t index) const 43 | { 44 | CheckIndex(index); 45 | 46 | return operator[](index); 47 | } 48 | 49 | T& At(const size_t index) 50 | { 51 | CheckIndex(index); 52 | 53 | return operator[](index); 54 | } 55 | 56 | const T& Front() const 57 | { 58 | if (front_.empty()) 59 | { 60 | return back_.front(); 61 | } 62 | 63 | return front_.back(); 64 | } 65 | 66 | T& Front() 67 | { 68 | if (front_.empty()) 69 | { 70 | return back_.front(); 71 | } 72 | 73 | return front_.back(); 74 | } 75 | 76 | const T& Back() const 77 | { 78 | if (back_.empty()) 79 | { 80 | return front_.front(); 81 | } 82 | 83 | return back_.back(); 84 | } 85 | 86 | T& Back() 87 | { 88 | if (back_.empty()) 89 | { 90 | return front_.front(); 91 | } 92 | 93 | return back_.back(); 94 | } 95 | 96 | void PushFront(const T& value) 97 | { 98 | front_.push_back(value); 99 | } 100 | 101 | void PushBack(const T& value) 102 | { 103 | back_.push_back(value); 104 | } 105 | 106 | private: 107 | std::vector front_, back_; 108 | 109 | void CheckIndex(const size_t index) 110 | { 111 | if (index >= Size()) 112 | { 113 | throw std::out_of_range("out of range"); 114 | } 115 | } 116 | }; -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_8/Task_8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Напишите шаблонный класс Deque, содержащий следующий набор методов: 3 | * конструктор по умолчанию; 4 | * константный метод Empty, возвращающий true, если дек не содержит ни одного элемента; 5 | * константный метод Size, возвращающий количество элементов в деке; 6 | * T& operator[](size_t index) и const T& operator[](size_t index) const; 7 | * константный и неконстантный метод At(size_t index), 8 | генерирующий стандартное исключение out_of_range, если индекс больше или равен количеству элементов в деке; 9 | * константные и неконстантные версии методов Front и Back, возвращающих ссылки на первый и последний элемент дека соответственно; 10 | * методы PushFront и PushBack. 11 | 12 | Неконстантные версии методов должны позволять изменять соответствующий элемент дека. 13 | 14 | Для реализации заведите внутри класса Deque два вектора: 15 | в один осуществляйте вставку в методе PushFront, а в другой — в методе PushBack. 16 | 17 | Замечание 18 | Заголовочный файл, который вы пришлёте на проверку, не должен подключать файлы , , , . 19 | Если у вас будет подключен один из этих файлов, вы получите ошибку компиляции. 20 | */ 21 | #include "Deque.h" 22 | #include "test_runner.h" 23 | #include "tests.h" 24 | 25 | #include 26 | 27 | int main() 28 | { 29 | TestRunner tr; 30 | RUN_TEST(tr, TestEmpty); 31 | RUN_TEST(tr, TestSize); 32 | RUN_TEST(tr, TestOperator); 33 | RUN_TEST(tr, TestAt); 34 | RUN_TEST(tr, TestFront); 35 | RUN_TEST(tr, TestBack); 36 | 37 | return 0; 38 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_8/tests.cpp: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | #include "Deque.h" 3 | #include "test_runner.h" 4 | 5 | void TestEmpty() 6 | { 7 | Deque deq; 8 | ASSERT_EQUAL(deq.Empty(), true); 9 | 10 | deq.PushBack(1); 11 | ASSERT_EQUAL(deq.Empty(), false); 12 | 13 | Deque d; 14 | ASSERT_EQUAL(d.Empty(), true); 15 | 16 | d.PushFront(2.0); 17 | ASSERT_EQUAL(d.Empty(), false); 18 | } 19 | 20 | void TestSize() 21 | { 22 | Deque deq; 23 | ASSERT_EQUAL(deq.Size(), 0); 24 | 25 | deq.PushBack(10); 26 | ASSERT_EQUAL(deq.Size(), 1); 27 | 28 | deq.PushFront(-10); 29 | ASSERT_EQUAL(deq.Size(), 2); 30 | 31 | for (int i = 5; i < 7; ++i) 32 | { 33 | deq.PushBack(i); 34 | deq.PushFront(i); 35 | } 36 | 37 | ASSERT_EQUAL(deq.Size(), 6); 38 | } 39 | 40 | void TestOperator() 41 | { 42 | Deque deq; 43 | 44 | deq.PushFront(1); 45 | ASSERT_EQUAL(deq[0], 1); 46 | 47 | deq.PushBack(2); 48 | ASSERT_EQUAL(deq[1], 2); 49 | 50 | deq.PushFront(-10); 51 | ASSERT_EQUAL(deq[1], 1); 52 | } 53 | 54 | void TestAt() 55 | { 56 | Deque deq; 57 | 58 | deq.PushFront(10); 59 | ASSERT_EQUAL(deq.At(0), 10); 60 | 61 | deq.PushFront(20); 62 | ASSERT_EQUAL(deq.At(1), 10); 63 | 64 | deq.PushBack(-10); 65 | ASSERT_EQUAL(deq.At(2), -10); 66 | 67 | for (int i = -20; i > -50; i -= 10) 68 | { 69 | deq.PushBack(i); 70 | } 71 | 72 | ASSERT_EQUAL(deq.At(5), -40); 73 | } 74 | 75 | void TestFront() 76 | { 77 | Deque deq; 78 | 79 | deq.PushBack(-100); 80 | ASSERT_EQUAL(deq.Front(), -100); 81 | 82 | deq.PushFront(100); 83 | ASSERT_EQUAL(deq.Front(), 100); 84 | } 85 | 86 | void TestBack() 87 | { 88 | Deque deq; 89 | 90 | deq.PushFront(std::numeric_limits::max()); 91 | ASSERT_EQUAL(deq.Back(), std::numeric_limits::max()); 92 | 93 | deq.PushBack(std::numeric_limits::min()); 94 | ASSERT_EQUAL(deq.Back(), std::numeric_limits::min()); 95 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_8/tests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void TestEmpty(); 4 | void TestSize(); 5 | void TestOperator(); 6 | void TestAt(); 7 | void TestFront(); 8 | void TestBack(); -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_9/Task_9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В лекции мы разработали функцию Head, которая позволяет пройтись циклом for по началу контейнера. 3 | В этой задаче мы сделаем шаг вперёд и разработаем шаблон Paginator, который разбивает содержимое контейнера на несколько страниц. 4 | Классический пример, когда такое может пригодиться на практике, — это распределение списка мобильных приложений по экранам телефона. 5 | Допустим, у нас есть вектор всех приложений нашего телефона и на одном экране мы можем разместить 20 иконок приложений. 6 | 7 | Итак, разработайте шаблон класса Paginator со следующими свойствами: 8 | * он имеет один шаблонный параметр — тип итератора 9 | * конструктор класса Paginator принимает три параметра: 10 | 1. Iterator begin 11 | 2. Iterator end — пара итераторов begin и end задают полуинтервал [begin; end), который мы будем нарезать на страницы 12 | 3. size_t page_size — размер одной страницы 13 | * по объектам класса Paginator можно проитерироваться с помощью цикла range-based for 14 | * класс Paginator имеет метод size_t size() const, 15 | который возвращает количество страниц, на которые был разбит переданный контейнер 16 | * сами страницы должны так же поддерживать итерацию с помощью range-based for и иметь метод size_t size() const, 17 | возвращающий количество объектов в этой странице 18 | * подробные примеры использования смотрите в юнит-тестах в шаблоне решения 19 | 20 | Кроме того разработайте шаблон функции Paginate, 21 | которая принимает ссылку на контейнер и размер страницы, и возвращает объект класса Paginator. 22 | 23 | Возможно, в шаблоне у вас будет некорректно работать вызов ASSERT_EQUAL в функции TestLooping. 24 | Разберитесь, почему это происходит, внесите правку в свою локальную версию файла test_runner.h, 25 | чтобы подобная ошибка не возникала в других задачах. 26 | */ 27 | #include "test_runner.h" 28 | #include "paginator.h" 29 | #include "tests.h" 30 | 31 | #include 32 | 33 | int main() 34 | { 35 | TestRunner tr; 36 | RUN_TEST(tr, TestPageCounts); 37 | RUN_TEST(tr, TestLooping); 38 | RUN_TEST(tr, TestModification); 39 | RUN_TEST(tr, TestPageSizes); 40 | RUN_TEST(tr, TestConstContainer); 41 | RUN_TEST(tr, TestPagePagination); 42 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_9/iterator_range.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | template 7 | class IteratorRange 8 | { 9 | public: 10 | IteratorRange(Iterator f, Iterator l) : first(f), last(l) {} 11 | 12 | Iterator begin() const { return first; } 13 | 14 | Iterator end() const { return last; } 15 | 16 | size_t size() const { return last - first; } 17 | 18 | private: 19 | Iterator first, last; 20 | }; 21 | 22 | template 23 | auto MakePage(Iterator f, Iterator l, size_t top) 24 | { 25 | return IteratorRange(f, std::next(f, std::min(top, (l - f)))); 26 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_9/paginator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "iterator_range.h" 4 | 5 | #include 6 | 7 | template 8 | class Paginator 9 | { 10 | public: 11 | Paginator(Iterator first, Iterator last, size_t page_size) 12 | { 13 | while (first != last) 14 | { 15 | _pages.push_back(MakePage(first, last, page_size)); 16 | first = _pages[_pages.size() - 1].end(); 17 | } 18 | } 19 | 20 | auto begin() const { return _pages.begin(); } 21 | 22 | auto end() const { return _pages.end(); } 23 | 24 | size_t size() const { return _pages.size(); } 25 | 26 | private: 27 | std::vector> _pages; 28 | }; 29 | 30 | template 31 | auto Paginate(Container& c, size_t page_size) 32 | { 33 | return Paginator(c.begin(), c.end(), page_size); 34 | } -------------------------------------------------------------------------------- /Red Belt/Week_1/Task_9/tests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | using namespace std; 4 | 5 | void TestPageCounts(); 6 | 7 | void TestLooping(); 8 | 9 | void TestModification(); 10 | 11 | void TestPageSizes(); 12 | 13 | void TestConstContainer(); 14 | 15 | void TestPagePagination(); -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В данной задаче необходимо оптимизировать код, использующийся для сортировки студентов по рейтингу. 3 | Данные каждого студента находятся в структуре Student, объявленной в файле student.h. 4 | Рейтинг студента записан в поле rating. 5 | 6 | Для сортировки студентов по рейтингу используется функция сравнения, возвращающая true, 7 | если рейтинг студента first выше рейтинга студента second. 8 | 9 | bool Compare(Student first, Student second) { 10 | return first.Less(second); 11 | } 12 | 13 | Было выявлено, что эта функция является узким местом процесса сортировки, и именно её нужно оптимизировать. 14 | 15 | Пришлите на проверку файл, содержащий оптимизированную версию функции Compare. 16 | Если ваша реализация будет недостаточно эффективной, то решение не уложится в ограничение по времени. 17 | */ 18 | #include "student.h" 19 | #include "test_runner.h" 20 | #include "profiler.h" 21 | 22 | #include 23 | 24 | using namespace std; 25 | 26 | 27 | bool Compare(const Student& first, const Student& second) 28 | { 29 | return first.Less(second); 30 | } 31 | 32 | void TestComparison() 33 | { 34 | LOG_DURATION("TestComparison"); 35 | 36 | Student newbie 37 | { 38 | "Ivan", "Ivanov", 39 | { 40 | {"c++", 1.0}, 41 | {"algorithms", 3.0} 42 | }, 43 | 2.0 44 | }; 45 | 46 | Student cpp_expert 47 | { 48 | "Petr", "Petrov", 49 | { 50 | {"c++", 9.5}, 51 | {"algorithms", 6.0} 52 | }, 53 | 7.75 54 | }; 55 | 56 | Student guru 57 | { 58 | "Sidor", "Sidorov", 59 | { 60 | {"c++", 10.0}, 61 | {"algorithms", 10.0} 62 | }, 63 | 10.0 64 | }; 65 | ASSERT(Compare(guru, newbie)); 66 | ASSERT(Compare(guru, cpp_expert)); 67 | ASSERT(!Compare(newbie, cpp_expert)); 68 | } 69 | 70 | void TestSorting() 71 | { 72 | LOG_DURATION("TestSorting"); 73 | 74 | vector students 75 | { 76 | {"Sidor", "Sidorov", {{"maths", 2.}}, 2.}, 77 | {"Semen", "Semenov", {{"maths", 4.}}, 4.}, 78 | {"Ivan", "Ivanov", {{"maths", 5.}}, 5.}, 79 | {"Petr", "Petrov", {{"maths", 3.}}, 3.}, 80 | {"Alexander", "Alexandrov", {{"maths", 1.}}, 1.} 81 | }; 82 | sort(students.begin(), students.end(), Compare); 83 | ASSERT(is_sorted(students.begin(), students.end(), 84 | [](Student first, Student second) { 85 | return first.Less(second); 86 | }) 87 | ); 88 | } 89 | 90 | int main() 91 | { 92 | LOG_DURATION("Total"); 93 | 94 | TestRunner tr; 95 | RUN_TEST(tr, TestComparison); 96 | RUN_TEST(tr, TestSorting); 97 | return 0; 98 | } -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_1/profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_1/student.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Student 9 | { 10 | string first_name; 11 | string last_name; 12 | map marks; 13 | double rating; 14 | 15 | bool operator < (const Student& other) const 16 | { 17 | return GetName() < other.GetName(); 18 | } 19 | 20 | bool Less(const Student& other) const 21 | { 22 | return rating > other.rating; 23 | } 24 | 25 | string GetName() const 26 | { 27 | return first_name + " " + last_name; 28 | } 29 | }; -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Студента попросили написать класс Learner, помогающий изучать иностранный язык. 3 | В публичном интерфейсе класса должны быть две функции: 4 | 5 | int Learn(const vector& words); 6 | vector KnownWords(); 7 | 8 | Функция Learn должна получать порцию слов, "запоминать" их и возвращать количество различных новых слов. 9 | Функция KnownWords должна возвращать отсортированный по алфавиту список всех выученных слов. В списке не должно быть повторов. 10 | 11 | Студент написал следующее решение этой задачи, однако оно почему-то работает очень медленно. 12 | Вам надо его ускорить. 13 | 14 | Вам дан файл learner.cpp с медленным решением задачи. 15 | Не меняя публичный интерфейс класса Learner, найдите в нём узкие места, 16 | исправьте их и сдайте переделанный класс в тестирующую систему. 17 | */ 18 | #include "learner.h" 19 | #include "profiler.h" 20 | 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | int main() 26 | { 27 | Learner learner; 28 | string line; 29 | while (getline(cin, line)) 30 | { 31 | vector words; 32 | stringstream ss(line); 33 | string word; 34 | while (ss >> word) 35 | { 36 | words.push_back(word); 37 | } 38 | { 39 | LOG_DURATION("Learn"); 40 | cout << learner.Learn(words) << "\n"; 41 | } 42 | 43 | } 44 | 45 | cout << "=== known words ===\n"; 46 | { 47 | LOG_DURATION("KnowWords"); 48 | for (auto word : learner.KnownWords()) 49 | { 50 | cout << word << "\n"; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_2/learner.cpp: -------------------------------------------------------------------------------- 1 | #include "learner.h" 2 | 3 | int Learner::Learn(const vector& words) 4 | { 5 | int newWords = 0; 6 | for (const auto& word : words) 7 | { 8 | if (dict.insert(word).second) 9 | { 10 | ++newWords; 11 | } 12 | } 13 | return newWords; 14 | } 15 | 16 | vector Learner::KnownWords() 17 | { 18 | return { dict.begin(), dict.end() }; 19 | } -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_2/learner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class Learner 11 | { 12 | private: 13 | set dict; 14 | 15 | public: 16 | int Learn(const vector& words); 17 | 18 | vector KnownWords(); 19 | }; 20 | -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_2/profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Red Belt/Week_2/Task_3/Task_3.cpp -------------------------------------------------------------------------------- /Red Belt/Week_2/Task_3/slow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class RouteManager 11 | { 12 | public: 13 | void AddRoute(int start, int finish) // Total: O(log(Q)) 14 | { 15 | reachable_lists_[start].push_back(finish); // O(log(Q) + Arm O(1)) 16 | reachable_lists_[finish].push_back(start); // O(log(Q) + Arm O(1)) 17 | } 18 | 19 | int FindNearestFinish(int start, int finish) const // Total: O(Q) 20 | { 21 | int result = abs(start - finish); // O(1) 22 | if (reachable_lists_.count(start) < 1) // O(log(Q) 23 | { 24 | return result; 25 | } 26 | 27 | const vector& reachable_stations = reachable_lists_.at(start); // O(1) 28 | 29 | if (!reachable_stations.empty()) // O(1) 30 | { 31 | result = min( // O(1) 32 | result, 33 | abs(finish - *min_element( // O(1) 34 | begin(reachable_stations), end(reachable_stations), 35 | [finish](int lhs, int rhs) { return abs(lhs - finish) < abs(rhs - finish); } // O(Q) 36 | )) 37 | ); 38 | } 39 | return result; 40 | } 41 | private: 42 | map> reachable_lists_; 43 | }; 44 | 45 | 46 | int main() // Total: O(Q^2) 47 | { 48 | RouteManager routes; 49 | 50 | int query_count; 51 | cin >> query_count; 52 | 53 | for (int query_id = 0; query_id < query_count; ++query_id) // O(Q) 54 | { 55 | string query_type; 56 | cin >> query_type; 57 | int start, finish; 58 | cin >> start >> finish; 59 | if (query_type == "ADD") 60 | { 61 | routes.AddRoute(start, finish); 62 | } else if (query_type == "GO") 63 | { 64 | cout << routes.FindNearestFinish(start, finish) << "\n"; 65 | } 66 | } 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Red Belt/Week_3/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В лекциях мы уже начали реализовывать свой вектор. 3 | В этой задаче вам надо его развить: добавить методы Size, Capacity и PushBack. 4 | Пришлите на проверку заголовочный файл simple_vector.h, 5 | содержащий объявление и определение шаблона класса SimpleVector. 6 | 7 | Требования: 8 | * метод Capacity должен возвращать текущую ёмкость вектора — количество элементов, 9 | которое помещается в блок памяти, выделенный вектором в данный момент 10 | * метод Size должен возвращать количество элементов в векторе 11 | * метод PushBack добавляет новый элемент в конец вектора; 12 | если в текущем выделенном блоке памяти не осталось свободного места (т.е. Size() == Capacity()), 13 | вектор должен выделить блок размера 2 * Capacity(), скопировать в него все элементы и удалить старый. 14 | * первый вызов метода PushBack для вновь созданного объекта должен делать ёмкость, равной единице 15 | * метод PushBack должен иметь амортизированную константную сложность 16 | * методы begin и end должны возвращать итераторы текущие начало и конец вектора 17 | * в деструкторе должен освобождаться текущий блок памяти, выделенный вектором 18 | * также см. дополнительные требования к работе SimpleVector в юнит-тестах в приложенном шаблоне решения 19 | 20 | Замечание 21 | Заголовочный файл, который вы пришлёте на проверку, 22 | не должен подключать файлы , , , , . 23 | Если у вас будет подключен один из этих файлов, вы получите ошибку компиляции. 24 | */ 25 | #include "simple_vector.h" 26 | #include "test_runner.h" 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | void TestConstruction() 34 | { 35 | SimpleVector empty; 36 | ASSERT_EQUAL(empty.Size(), 0u); 37 | ASSERT_EQUAL(empty.Capacity(), 0u); 38 | ASSERT(empty.begin() == empty.end()); 39 | 40 | SimpleVector five_strings(5); 41 | ASSERT_EQUAL(five_strings.Size(), 5u); 42 | ASSERT(five_strings.Size() <= five_strings.Capacity()); 43 | for (auto& item : five_strings) 44 | { 45 | ASSERT(item.empty()); 46 | } 47 | five_strings[2] = "Hello"; 48 | ASSERT_EQUAL(five_strings[2], "Hello"); 49 | } 50 | 51 | void TestPushBack() 52 | { 53 | SimpleVector v; 54 | for (int i = 10; i >= 1; --i) 55 | { 56 | v.PushBack(i); 57 | ASSERT(v.Size() <= v.Capacity()); 58 | } 59 | std::sort(std::begin(v), std::end(v)); 60 | 61 | const std::vector expected = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 62 | ASSERT_EQUAL(v.Size(), expected.size()); 63 | ASSERT(equal(std::begin(v), std::end(v), std::begin(expected))); 64 | } 65 | 66 | int main() 67 | { 68 | TestRunner tr; 69 | RUN_TEST(tr, TestConstruction); 70 | RUN_TEST(tr, TestPushBack); 71 | return 0; 72 | } -------------------------------------------------------------------------------- /Red Belt/Week_3/Task_3/simple_vector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | template 7 | class SimpleVector 8 | { 9 | public: 10 | SimpleVector() = default; 11 | 12 | explicit SimpleVector(size_t size) 13 | : data_(new T[size]) 14 | , size_(size) 15 | , capacity_(size) 16 | { 17 | } 18 | 19 | ~SimpleVector() 20 | { 21 | delete[] data_; 22 | } 23 | 24 | T& operator[](size_t index) 25 | { 26 | return data_[index]; 27 | } 28 | 29 | T* begin() 30 | { 31 | return data_; 32 | } 33 | 34 | T* end() 35 | { 36 | return data_ + size_; 37 | } 38 | 39 | size_t Size() const 40 | { 41 | return size_; 42 | } 43 | 44 | size_t Capacity() const 45 | { 46 | return capacity_; 47 | } 48 | 49 | void PushBack(const T& value) 50 | { 51 | if (size_ >= capacity_) 52 | { 53 | size_t new_capacity = capacity_ == 0 ? 1 : 2 * capacity_; 54 | T* new_data = new T[new_capacity]; 55 | std::copy(begin(), end(), new_data); 56 | delete[] data_; 57 | data_ = new_data; 58 | capacity_ = new_capacity; 59 | } 60 | data_[size_++] = value; 61 | } 62 | 63 | private: 64 | T* data_ = nullptr; 65 | size_t size_ = 0; 66 | size_t capacity_ = 0; 67 | }; -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | У каждого спортсмена на футболке написан уникальный номер. 3 | Спортсмены по очереди выходят из раздевалки и должны построиться на стадионе. 4 | Тренер каждому выходящему спортсмену называет номер того спортсмена, перед которым нужно встать. 5 | Если спортсмена с названным номером на поле нет, то нужно встать в конец шеренги. 6 | 7 | В стандартном вводе сначала задано натуральное число n, не превосходящее 100000, — количество спортсменов. 8 | Далее идут n пар неотрицательных целых чисел, не превосходящих 100000. 9 | Первое число в паре — номер очередного выходящего спортсмена. 10 | Второе число в паре — номер того спортсмена, перед которым должен встать текущий. 11 | 12 | Напечатайте в стандартный вывод номера спортсменов в порядке построения на поле. 13 | 14 | Ограничение по времени — 0,8 с. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int main() 22 | { 23 | const int MAX_SPORTSMEN = 100'000; 24 | 25 | using Position = std::list::iterator; 26 | 27 | size_t n_sportsmen; 28 | std::cin >> n_sportsmen; 29 | 30 | std::list sportsmen; 31 | std::vector sportsmen_pos(MAX_SPORTSMEN + 1, sportsmen.begin()); 32 | 33 | for (size_t i = 0; i < n_sportsmen; ++i) 34 | { 35 | int pos, next_pos; 36 | std::cin >> pos >> next_pos; 37 | sportsmen_pos[pos] = sportsmen.insert(sportsmen_pos[next_pos], pos); 38 | } 39 | 40 | for (auto& i : sportsmen) 41 | { 42 | std::cout << i << '\n'; 43 | } 44 | } -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_2/profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_2/stack_vector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | template 7 | class StackVector 8 | { 9 | public: 10 | explicit StackVector(size_t a_size = 0) 11 | :size_(a_size) 12 | { 13 | if (size_ > N) 14 | { 15 | throw std::invalid_argument("invalid argument"); 16 | } 17 | } 18 | 19 | T& operator[](size_t index) 20 | { 21 | return stack_vector_[index]; 22 | } 23 | 24 | const T& operator[](size_t index) const 25 | { 26 | return stack_vector_[index]; 27 | } 28 | 29 | const auto begin() const 30 | { 31 | return stack_vector_.begin(); 32 | } 33 | const auto end() const 34 | { 35 | //return stack_vector_[size_]; 36 | return stack_vector_.begin() + size_; 37 | } 38 | 39 | auto begin() 40 | { 41 | return stack_vector_.begin(); 42 | } 43 | auto end() 44 | { 45 | return stack_vector_.begin() + size_; 46 | } 47 | size_t Capacity() const 48 | { 49 | return stack_vector_.size(); 50 | } 51 | 52 | size_t Size() const 53 | { 54 | return size_; 55 | } 56 | 57 | void PushBack(const T& value) 58 | { 59 | if (size_ >= N) 60 | { 61 | throw std::overflow_error("overflow_error"); 62 | } 63 | 64 | stack_vector_[size_++] = value; 65 | } 66 | T PopBack() 67 | { 68 | if (size_ == 0) 69 | { 70 | throw std::underflow_error("underflow_error"); 71 | } 72 | 73 | return stack_vector_[--size_]; 74 | } 75 | 76 | private: 77 | size_t size_; 78 | std::array stack_vector_; 79 | }; -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_4/profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_5/profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_6/http_request.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct HttpRequest 6 | { 7 | std::string_view method, uri, protocol; 8 | }; -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_6/profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_6/stats.cpp: -------------------------------------------------------------------------------- 1 | #include "stats.h" 2 | 3 | #include 4 | 5 | Stats::Stats() 6 | { 7 | Initialization(known_methods_, methods_); 8 | methods_[unknown_method] = 0; 9 | Initialization(known_uri_, uri_); 10 | uri_[unknown_uri] = 0; 11 | } 12 | 13 | void Stats::AddMethod(std::string_view method) 14 | { 15 | if (methods_.count(method)) 16 | { 17 | ++methods_[method]; 18 | } 19 | else 20 | { 21 | ++methods_[unknown_method]; 22 | } 23 | } 24 | 25 | void Stats::AddUri(std::string_view uri) 26 | { 27 | if (uri_.count(uri)) 28 | { 29 | ++uri_[uri]; 30 | } 31 | else 32 | { 33 | ++uri_[unknown_uri]; 34 | } 35 | } 36 | 37 | const std::map& Stats::GetMethodStats() const 38 | { 39 | return methods_; 40 | } 41 | 42 | const std::map& Stats::GetUriStats() const 43 | { 44 | return uri_; 45 | } 46 | 47 | void RemoveSpaces(std::string_view& line) 48 | { 49 | while (!line.empty() && std::isspace(line[0])) 50 | { 51 | line.remove_prefix(1); 52 | } 53 | } 54 | 55 | std::string_view ParseSV(std::string_view& line) 56 | { 57 | RemoveSpaces(line); 58 | size_t index = line.find(' '); 59 | std::string_view result = line.substr(0, index); 60 | line.remove_prefix(index + 1); 61 | 62 | return result; 63 | } 64 | 65 | HttpRequest ParseRequest(std::string_view line) 66 | { 67 | std::string_view method = ParseSV(line); 68 | std::string_view uri = ParseSV(line); 69 | std::string_view protocol = ParseSV(line); 70 | return { method, uri, protocol }; 71 | } -------------------------------------------------------------------------------- /Red Belt/Week_4/Task_6/stats.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "http_request.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class Stats 10 | { 11 | public: 12 | void AddMethod(std::string_view method); 13 | void AddUri(std::string_view uri); 14 | const std::map& GetMethodStats() const; 15 | const std::map& GetUriStats() const; 16 | Stats(); 17 | 18 | private: 19 | std::map methods_; 20 | std::map uri_; 21 | 22 | static const size_t KNOWN_METHODS_SIZE = 4; 23 | inline static const std::array known_methods_ = 24 | { 25 | "GET", "POST", "PUT", "DELETE" 26 | }; 27 | inline static const std::string unknown_method = "UNKNOWN"; 28 | 29 | static const size_t KNOWN_URI_SIZE = 5; 30 | inline static const std::array known_uri_ = 31 | { 32 | "/", "/order", "/product", "/basket", "/help", 33 | }; 34 | inline static const std::string unknown_uri = "unknown"; 35 | 36 | template 37 | void Initialization(const Container& c, Init_Container& init) 38 | { 39 | for (const auto& x : c) 40 | { 41 | init[x] = 0; 42 | } 43 | } 44 | }; 45 | 46 | HttpRequest ParseRequest(std::string_view line); -------------------------------------------------------------------------------- /Red Belt/Week_5/Task_10/profile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /Red Belt/Week_5/Task_11/profile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /Red Belt/Week_5/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В видеолекции мы с вами познакомились с конструктором копирования и оператором присваивания, 3 | а также написали конструктор копирования для SimpleVector. 4 | В этой задаче вам нужно реализовать оператор присваивания для SimpleVector. 5 | Вам дан cpp-файл, который подключает заголовочный файл simple_vector.h и содержит небольшой набор юнит-тестов. 6 | Пришлите на проверку файл simple_vector.h с реализацией оператора присваивания. 7 | */ 8 | #include "simple_vector.h" 9 | #include "test_runner.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | void TestCopyAssignment() 16 | { 17 | SimpleVector numbers(10); 18 | std::iota(numbers.begin(), numbers.end(), 1); 19 | 20 | SimpleVector dest; 21 | ASSERT_EQUAL(dest.Size(), 0u); 22 | 23 | dest = numbers; 24 | ASSERT_EQUAL(dest.Size(), numbers.Size()); 25 | ASSERT(dest.Capacity() >= dest.Size()); 26 | ASSERT(std::equal(dest.begin(), dest.end(), numbers.begin())); 27 | } 28 | 29 | int main() 30 | { 31 | TestRunner tr; 32 | RUN_TEST(tr, TestCopyAssignment); 33 | } -------------------------------------------------------------------------------- /Red Belt/Week_5/Task_3/simple_vector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | template 6 | class SimpleVector 7 | { 8 | public: 9 | SimpleVector() = default; 10 | 11 | explicit SimpleVector(size_t size) 12 | : data_(new T[size]) 13 | , size_(size) 14 | , capacity_(size) 15 | { 16 | } 17 | 18 | SimpleVector(const SimpleVector& other) 19 | : data_(new T[other.capacity_]) 20 | , size_(other.size_) 21 | , capacity_(other.capacity_) 22 | { 23 | std::copy(other.begin(), other.end(), begin()); 24 | } 25 | 26 | void operator=(const SimpleVector& other) 27 | { 28 | if (other.size_ <= capacity_) 29 | { 30 | std::copy(other.begin(), other.end(), begin()); 31 | size_ = other.size_; 32 | } 33 | else 34 | { 35 | SimpleVector tmp(other); 36 | std::swap(tmp.data_, data_); 37 | std::swap(tmp.size_, size_); 38 | std::swap(tmp.capacity_, capacity_); 39 | } 40 | } 41 | 42 | ~SimpleVector() 43 | { 44 | delete[] data_; 45 | } 46 | 47 | T& operator[](size_t index) 48 | { 49 | return data_[index]; 50 | } 51 | 52 | T* begin() 53 | { 54 | return data_; 55 | } 56 | 57 | T* end() 58 | { 59 | return data_ + size_; 60 | } 61 | 62 | const T* begin() const 63 | { 64 | return data_; 65 | } 66 | 67 | const T* end() const 68 | { 69 | return data_ + size_; 70 | } 71 | 72 | size_t Size() const 73 | { 74 | return size_; 75 | } 76 | 77 | size_t Capacity() const 78 | { 79 | return capacity_; 80 | } 81 | 82 | void PushBack(const T& value) 83 | { 84 | if (size_ >= capacity_) 85 | { 86 | size_t new_capacity = capacity_ == 0 ? 1 : 2 * capacity_; 87 | T* new_data = new T[new_capacity]; 88 | std::copy(begin(), end(), new_data); 89 | delete[] data_; 90 | data_ = new_data; 91 | capacity_ = new_capacity; 92 | } 93 | data_[size_++] = value; 94 | } 95 | 96 | private: 97 | T* data_ = nullptr; 98 | size_t size_ = 0; 99 | size_t capacity_ = 0; 100 | }; -------------------------------------------------------------------------------- /Red Belt/Week_5/Task_5/Task_5.cpp: -------------------------------------------------------------------------------- 1 | #include "simple_vector_2.h" 2 | #include "test_runner.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | void TestConstruction() 11 | { 12 | SimpleVector empty; 13 | ASSERT_EQUAL(empty.Size(), 0u); 14 | ASSERT_EQUAL(empty.Capacity(), 0u); 15 | ASSERT(empty.begin() == empty.end()); 16 | 17 | SimpleVector five_strings(5); 18 | ASSERT_EQUAL(five_strings.Size(), 5u); 19 | ASSERT(five_strings.Size() <= five_strings.Capacity()); 20 | for (auto& item : five_strings) 21 | { 22 | ASSERT(item.empty()); 23 | } 24 | five_strings[2] = "Hello"; 25 | ASSERT_EQUAL(five_strings[2], "Hello"); 26 | } 27 | 28 | void TestPushBack() 29 | { 30 | SimpleVector v; 31 | for (int i = 10; i >= 1; --i) 32 | { 33 | v.PushBack(i); 34 | ASSERT(v.Size() <= v.Capacity()); 35 | } 36 | std::sort(std::begin(v), std::end(v)); 37 | 38 | const std::vector expected = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 39 | ASSERT(std::equal(std::begin(v), std::end(v), std::begin(expected))); 40 | } 41 | 42 | class StringNonCopyable : public std::string 43 | { 44 | public: 45 | using std::string::string; 46 | StringNonCopyable(std::string&& other) : std::string(move(other)) {} 47 | StringNonCopyable(const StringNonCopyable&) = delete; 48 | StringNonCopyable(StringNonCopyable&&) = default; 49 | StringNonCopyable& operator=(const StringNonCopyable&) = delete; 50 | StringNonCopyable& operator=(StringNonCopyable&&) = default; 51 | }; 52 | 53 | void TestNoCopy() 54 | { 55 | SimpleVector strings; 56 | static const int SIZE = 10; 57 | for (int i = 0; i < SIZE; ++i) 58 | { 59 | strings.PushBack(StringNonCopyable(std::to_string(i))); 60 | } 61 | for (int i = 0; i < SIZE; ++i) 62 | { 63 | ASSERT_EQUAL(strings[i], std::to_string(i)); 64 | } 65 | } 66 | 67 | int main() 68 | { 69 | TestRunner tr; 70 | RUN_TEST(tr, TestConstruction); 71 | RUN_TEST(tr, TestPushBack); 72 | RUN_TEST(tr, TestNoCopy); 73 | return 0; 74 | } -------------------------------------------------------------------------------- /Red Belt/Week_5/Task_5/simple_vector_2.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Реализуйте SimpleVector в этом файле 6 | // и отправьте его на проверку 7 | 8 | template 9 | class SimpleVector 10 | { 11 | public: 12 | SimpleVector() = default; 13 | 14 | explicit SimpleVector(size_t size) 15 | : data_(new T[size]) 16 | , capacity_(size) 17 | , size_(size) 18 | { 19 | } 20 | 21 | SimpleVector(SimpleVector&& other) 22 | : data_(other.data_) 23 | , capacity_(other.capacity_) 24 | , size_(other.size_) 25 | { 26 | other.data_ = nullptr; 27 | other.capacity_ = other.size_ = 0; 28 | } 29 | 30 | ~SimpleVector() 31 | { 32 | delete[] data_; 33 | capacity_ = size_ = 0; 34 | } 35 | 36 | void operator= (SimpleVector&& other) 37 | { 38 | delete[] data_; 39 | data_ = other.data_; 40 | capacity_ = other.capacity_; 41 | size_ = other.size_; 42 | 43 | other.data_ = nullptr; 44 | other.capacity_ = other.size_ = 0; 45 | } 46 | 47 | T& operator[](size_t index) 48 | { 49 | return data_[index]; 50 | } 51 | 52 | T* begin() 53 | { 54 | return data_; 55 | } 56 | T* end() 57 | { 58 | return data_ + size_; 59 | } 60 | 61 | const T* begin() const 62 | { 63 | return data_; 64 | } 65 | const T* end() const 66 | { 67 | return data_ + size_; 68 | } 69 | 70 | size_t Size() const 71 | { 72 | return size_; 73 | } 74 | size_t Capacity() const 75 | { 76 | return capacity_; 77 | } 78 | 79 | void PushBack(T value) 80 | { 81 | if (size_ >= capacity_) 82 | { 83 | size_t new_cap = capacity_ == 0 ? 1 : capacity_ * 2; 84 | T* new_data = new T[new_cap]; 85 | std::move(begin(), end(), temp); 86 | 87 | delete[] data_; 88 | data_ = new_data; 89 | capacity_ = new_cap; 90 | } 91 | data_[size_++] = std::move(value); 92 | } 93 | 94 | private: 95 | T* data_ = nullptr; 96 | size_t size_ = 0; 97 | size_t capacity_ = 0; 98 | }; 99 | -------------------------------------------------------------------------------- /Red Belt/Week_5/Task_9/profile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class LogDuration 8 | { 9 | public: 10 | explicit LogDuration(const std::string& message = {}) 11 | : _message(message + ": ") 12 | , _start(std::chrono::steady_clock::now()) 13 | { 14 | } 15 | 16 | ~LogDuration() 17 | { 18 | auto finish = std::chrono::steady_clock::now(); 19 | auto duration = finish - _start; 20 | std::cerr << _message 21 | << std::chrono::duration_cast(duration).count() 22 | << " ms" << std::endl; 23 | } 24 | private: 25 | std::string _message; 26 | std::chrono::steady_clock::time_point _start; 27 | }; 28 | 29 | #define UNIQ_ID_IMPL(lineno) _a_local_var_##lineno 30 | #define UNIQ_ID(lineno) UNIQ_ID_IMPL(lineno) 31 | 32 | #define LOG_DURATION(message) \ 33 | LogDuration UNIQ_ID(__LINE__) {message}; -------------------------------------------------------------------------------- /White Belt/Readme.md: -------------------------------------------------------------------------------- 1 | # C++: белый пояс 2 | 3 | [Основы разработки на C++: белый пояс](https://www.coursera.org/learn/c-plus-plus-white/) by Moscow Institute of Physics and Technology & Yandex 4 | 5 | ## Об этом курсе 6 | 7 | Этот курс посвящён знакомству с языком программирования С++. Вы научитесь использовать его основные конструкции, создавать свои типы данных, разбивать программу на классы и функции. 8 | В конце курса вас ждёт финальный проект: вы сможете самостоятельно реализовать простое хранилище данных с возможностью добавления, удаления и поиска. 9 | 10 | Курс разработан ведущими специалистами Яндекса и преподавателями Школы анализа данных. За их плечами – годы разработки сервисов поиска, рекламы и инфраструктуры. 11 | 12 | Логическим продолжением курса станет специализация «Искусство разработки на современном C++». 13 | 14 | ## Программа курса 15 | 16 | ### [1. Знакомство с искусством C++](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/White%20Belt/Week_1) 17 | 18 | Задачи обучения: 19 | * Написать первую программу на С++ 20 | * Применить все самые частые конструкции языка своими руками: ввод и вывод в стандартные потоки, условные операторы, циклы 21 | * Узнать основные типы данных языка С++ 22 | 23 | ### [2. Техника владения функциями и контейнерами](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/White%20Belt/Week_2) 24 | 25 | Задачи обучения: 26 | * Применять функции в С++ 27 | * Применять контейнер vector 28 | * Применять контейнер map 29 | * Применять контейнер set 30 | 31 | ### [3. Медитация над алгоритмами и классами](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/White%20Belt/Week_3) 32 | Задачи обучения: 33 | * Применять алгоритмы 34 | * Знать видимость и инициализацию переменных 35 | * Структуры и классы 36 | * Константность методов 37 | * Конструкторы 38 | 39 | ### [4. Ката по вводу/выводу, исключениям и перегрузке операторов](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/White%20Belt/Week_4) 40 | 41 | Задачи обучения: 42 | * Структуры Date 43 | * Класс Function 44 | * Текстовые файлы и потоки 45 | * Исключения 46 | 47 | ### [5. Первое кумитэ](https://github.com/m3nf1s/Modern-Cplusplus/tree/master/White%20Belt/Week_5%20(Final_project)) 48 | 49 | Задачи обучения: 50 | * Базы данных 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /White Belt/Week_1/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* На вход программе через стандартный ввод передаются два целых числа, по модулю не превышающие 100000. 2 | * Выведите в стандартный вывод их сумму. 3 | */ 4 | 5 | #include 6 | 7 | using namespace std; 8 | 9 | int main() 10 | { 11 | int a, b; 12 | 13 | cin >> a >> b; 14 | cout << a + b << endl; 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * В стандартном потоке даны три строки, разделённые пробелом. 3 | * Каждая строка состоит из строчных латинских букв и имеет длину не более 30 символов. 4 | * Выведите в стандартный вывод лексикографически минимальную из них. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | string a, b, c; 15 | cin >> a >> b >> c; 16 | 17 | if (a < b) 18 | { 19 | if (a < c) 20 | cout << a << endl; 21 | else 22 | cout << c << endl; 23 | } 24 | else 25 | { 26 | if (b < c) 27 | cout << b << endl; 28 | else 29 | cout << c << endl; 30 | } 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * На вход вашей программе в стандартном вводе даны действительные коэффициенты A, B и C уравнения Ax² + Bx + C = 0. 3 | * Выведите все его различные действительные корни в любом порядке. 4 | * Гарантируется, что хотя бы один из коэффициентов не равен нулю. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | double a, b, c; 15 | 16 | cin >> a >> b >> c; 17 | 18 | if (a != 0) 19 | { 20 | const double D = sqrt(pow(b, 2) - 4 * a * c); 21 | 22 | if (D > 0) 23 | cout << (-b + D) / (2 * a) << ' ' << (-b - D) / (2 * a) << endl; 24 | else 25 | if (D == 0) 26 | cout << (-b - D) / (2 * a) << endl; 27 | } 28 | else 29 | { 30 | if (b != 0) 31 | cout << -c / b << endl; 32 | } 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Task_4/Task_4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Дано два натуральных числа A и B, не превышающих 1 000 000. 3 | * Напишите программу, которая вычисляет целую часть частного от деления A на B. 4 | * Если B = 0, выведите "Impossible". 5 | */ 6 | 7 | #include 8 | 9 | using namespace std; 10 | 11 | 12 | int main() 13 | { 14 | int a, b; 15 | 16 | cin >> a >> b; 17 | 18 | if (b != 0) 19 | cout << a / b << endl; 20 | else 21 | cout << "Impossible" << endl; 22 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Task_5/Task_5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Написать программу вычисления стоимости покупки с учётом скидки. 3 | * Скидка в X процентов предоставляется, если сумма покупки больше A рублей, в Y процентов - если сумма больше B рублей. 4 | * В стандартном вводе содержится пять вещественных чисел, разделённых пробелом: N, A, B, X, Y (A < B) - где N - исходная стоимость товара. 5 | * Выведите стоимость покупки с учётом скидки. 6 | */ 7 | 8 | #include 9 | 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | double n, a, b, x, y; 15 | 16 | cin >> n >> a >> b >> x >> y; 17 | 18 | 19 | if (n > 0 && a > 0 && b > 0 && x > 0 && y > 0 && x <= 100 && y <= 100) 20 | { 21 | if (a < b && x < y) 22 | { 23 | if (n < a) 24 | cout << n << endl; 25 | else 26 | if (n >= a && n < b) 27 | cout << n * (100 - x) / 100 << endl; 28 | else 29 | if (n >= b) 30 | cout << n * (100 - y) / 100 << endl; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Task_6/Task_6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Дано два целых числа A и B (A <= B, A >= 1, B <= 30000). 3 | * Выведите через пробел все чётные числа от A до B (включительно). 4 | * Для проверки целого числа x на чётность используется операция взятия остатка от деления на 2, которая в C++ оформляется с помощью символа "%". 5 | */ 6 | 7 | #include 8 | 9 | using namespace std; 10 | 11 | int main() 12 | { 13 | int a, b; 14 | 15 | cin >> a >> b; 16 | 17 | if (a >= 1 && b <= 30000 && a < b) 18 | { 19 | for (int i = a; i <= b; i++) 20 | { 21 | if (i % 2 == 0) 22 | cout << i << " "; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Task_7/Task_7.cpp: -------------------------------------------------------------------------------- 1 | /* Дана строка. 2 | * Найдите в этой строке второе вхождение буквы f и выведите индекс этого вхождения. 3 | * Если буква f в данной строке встречается только один раз, выведите число -1, а если не встречается ни разу, выведите число -2. 4 | * Индексы нумеруются с нуля. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | int main() 13 | { 14 | string word; 15 | cin >> word; 16 | int itr = 0; 17 | int buff; 18 | for (int i = 0; i < word.size(); i++) 19 | { 20 | if (word[i] == 'f') 21 | { 22 | itr++; 23 | if (itr == 2) 24 | { 25 | buff = i; 26 | break; 27 | } 28 | } 29 | } 30 | 31 | if (itr == 2) 32 | cout << buff << endl; 33 | else 34 | if (itr == 1) 35 | cout << -1 << endl; 36 | else 37 | cout << -2 << endl; 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Task_8/Task_8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * В stdin даны два натуральных числа. 3 | * Выведите в stdout их наибольший общий делитель. 4 | */ 5 | 6 | #include 7 | 8 | using namespace std; 9 | 10 | int main() 11 | { 12 | int number1, number2; 13 | 14 | cin >> number1 >> number2; 15 | 16 | while (number1 > 0 && number2 > 0) 17 | { 18 | if (number1 > number2) 19 | number1 %= number2; 20 | else 21 | number2 %= number1; 22 | } 23 | 24 | cout << number1 + number2; 25 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Task_9/Task_9.cpp: -------------------------------------------------------------------------------- 1 | /* На вход дано целое положительное число N. 2 | * Выведите его в двоичной системе счисления без ведущих нулей. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | int main() 11 | { 12 | vector vec; 13 | int number; 14 | 15 | cin >> number; 16 | 17 | while (number != 0) 18 | { 19 | vec.push_back(number % 2); 20 | number /= 2; 21 | } 22 | 23 | for (int i = vec.size() - 1; i >= 0; i--) 24 | { 25 | cout << vec[i]; 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /White Belt/Week_1/Updated/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * В стандартном потоке даны три строки, разделённые пробелом. 3 | * Каждая строка состоит из строчных латинских букв и имеет длину не более 30 символов. 4 | * Выведите в стандартный вывод лексикографически минимальную из них. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | std::string word1, word2, word3; 13 | std::cin >> word1 >> word2 >> word3; 14 | 15 | std::cout << std::min({ word1, word2, word3 }); 16 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Updated/Task_5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | double original_price, first_discount_price, second_discount_price, first_discount_percent, second_discount_percent; 6 | double discount_percent = 0; 7 | 8 | std::cin >> original_price >> first_discount_price >> second_discount_price >> first_discount_percent >> second_discount_percent; 9 | 10 | if(original_price > first_discount_price && original_price <= second_discount_price) 11 | { 12 | discount_percent = first_discount_percent; 13 | } 14 | else if (original_price > second_discount_price) 15 | { 16 | discount_percent = second_discount_percent; 17 | } 18 | 19 | std::cout << original_price * (1 - discount_percent / 100); 20 | } -------------------------------------------------------------------------------- /White Belt/Week_1/Updated/Task_9.cpp: -------------------------------------------------------------------------------- 1 | /* На вход дано целое положительное число N. 2 | * Выведите его в двоичной системе счисления без ведущих нулей. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | int main() 9 | { 10 | int number; 11 | std::cin >> number; 12 | size_t bits { 0 }; 13 | 14 | for(int temp = number; temp != 0; temp /= 2) 15 | { 16 | ++bits; 17 | } 18 | 19 | std::vector binary_number(bits); 20 | 21 | for(size_t i = 0; i < binary_number.size(); ++i, number /= 2) 22 | { 23 | binary_number[i] = number % 2; 24 | } 25 | 26 | for(auto it = binary_number.crbegin(); it != binary_number.crend(); ++it) 27 | { 28 | std::cout << *it; 29 | } 30 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Напишите функцию, которая 3 | * называется Factorial 4 | * возвращает int 5 | * принимает int и возвращает факториал своего аргумента. 6 | * Гарантируется, что аргумент функции по модулю не превышает 10. Для отрицательных аргументов функция должна возвращать 1. 7 | */ 8 | 9 | #include 10 | 11 | int Factorial (int number) 12 | { 13 | int fac = 1; 14 | if (number > 1) 15 | { 16 | for (int i = 2; i <= number; i++) 17 | { 18 | fac *= i; 19 | } 20 | } 21 | return fac; 22 | } 23 | 24 | int main() 25 | { 26 | int number; 27 | std::cin >> number; 28 | std::cout << Factorial(number) << std::endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /White Belt/Week_2/Task_11/Task_11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Слова называются анаграммами друг друга, если одно из них можно получить перестановкой букв в другом. 3 | * Например, слово «eat» можно получить перестановкой букв слова «tea», поэтому эти слова являются анаграммами друг друга. 4 | * Даны пары слов, проверьте для каждой из них, являются ли слова этой пары анаграммами друг друга. 5 | * 6 | * Указание 7 | * Один из способов проверки того, являются ли слова анаграммами друг друга, заключается в следующем. 8 | * Для каждого слова с помощью словаря подсчитаем, сколько раз в нём встречается каждая буква. 9 | * Если для обоих слов эти словари равны (а это проверяется с помощью обычного оператора ==), то слова являются анаграммами друг друга, в противном случае не являются. 10 | * 11 | * При этом построение такого словаря по слову удобно вынести в отдельную функцию BuildCharCounters. 12 | * 13 | * Формат ввода 14 | * Сначала дано число пар слов N, затем в N строках содержатся пары слов, которые необходимо проверить. 15 | * Гарантируется, что все слова состоят лишь из строчных латинских букв. 16 | * 17 | * Формат вывода 18 | * Выведите N строк: для каждой введённой пары слов YES, если эти слова являются анаграммами, и NO в противном случае. 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | std::map BuildCharCounters (const std::string& word) 27 | { 28 | std::map result; 29 | 30 | for (int i = 0; i < word.length(); i++) 31 | result[word[i]]++; 32 | 33 | return result; 34 | } 35 | 36 | int main() 37 | { 38 | int countWords; 39 | std::vector answers; 40 | 41 | std::cin >> countWords; 42 | 43 | for (int i = 0; i < countWords; i++) 44 | { 45 | std::string firstWord, secondWord; 46 | std::cin >> firstWord >> secondWord; 47 | 48 | if (BuildCharCounters(firstWord) == BuildCharCounters(secondWord)) 49 | answers.push_back("YES"); 50 | else 51 | answers.push_back("NO"); 52 | } 53 | 54 | for (const auto& answer : answers) 55 | { 56 | std::cout << answer << std::endl; 57 | } 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_14/Task_14.cpp: -------------------------------------------------------------------------------- 1 | /*В этой задаче вам нужно присваивать номера автобусным маршрутам. 2 | * 3 | *А именно, для каждого маршрута, заданного набором названий остановок, нужно либо выдать новый номер (первому маршруту — 1, второму — 2 и т. д.), 4 | *либо вернуть номер существующего маршрута, которому соответствует такой набор остановок. 5 | * 6 | *Наборы остановок, полученные друг из друга перестановкой остановок, считаются различными (см. пример). 7 | * 8 | *Указание 9 | *В C++ ключом словаря может быть не только число или строка, но и другой контейнер, например, vector. 10 | * 11 | *Формат ввода 12 | *Сначала вводится количество запросов Q, затем Q описаний запросов. 13 | * 14 | *Каждый запрос представляет собой положительное количество остановок N, за которым следуют разделённые пробелом N различных названий остановок соответствующего маршрута. 15 | *Названия остановок состоят лишь из латинских букв и символов подчёркивания. 16 | * 17 | *Формат вывода 18 | *Выведите ответ на каждый запрос в отдельной строке. 19 | * 20 | *Если маршрут с данным набором остановок уже существует, в ответ на соответствующий запрос выведите Already exists for i, где i — номер маршрута с таким набором остановок. 21 | *В противном случае нужно выделить введённому набору остановок новый номер i и вывести его в формате New bus i.*/ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | std::map, int> number_bus_routes; 31 | int command_count, number_route = 0; 32 | 33 | std::cin >> command_count; 34 | 35 | for (int i = 0; i < command_count; i++) 36 | { 37 | int stops_count = 0; 38 | 39 | std::vector stops; 40 | 41 | std::cin >> stops_count; 42 | 43 | for (int j = 0; j < stops_count; j++) 44 | { 45 | std::string stop_name; 46 | std::cin >> stop_name; 47 | 48 | stops.push_back(stop_name); 49 | } 50 | 51 | if (number_bus_routes.count(stops) == 0) 52 | { 53 | number_bus_routes[stops] = ++number_route; 54 | std::cout << "New bus " << number_bus_routes[stops] << std::endl; 55 | 56 | } 57 | else 58 | { 59 | std::cout << "Already exists for " << number_bus_routes[stops] << std::endl; 60 | } 61 | 62 | stops.clear(); 63 | } 64 | 65 | return 0; 66 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_15/Task_15.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Дан набор строк. Найдите количество уникальных строк в этом наборе. 3 | * 4 | * Формат ввода 5 | * Сначала вводится количество строк N, затем — сами N строк, разделённые пробелом. 6 | * Все строки состоят лишь из латинских букв, цифр и символов подчёркивания. 7 | * 8 | * Формат вывода 9 | * Выведите единственное целое число — количество уникальных строк в данном наборе. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | int main() 17 | { 18 | std::set unique_string; 19 | 20 | int command_count; 21 | std::cin >> command_count; 22 | 23 | for (int i = 0; i < command_count; i++) 24 | { 25 | std::string word; 26 | std::cin >> word; 27 | 28 | unique_string.insert(word); 29 | } 30 | 31 | std::cout << unique_string.size() << std::endl; 32 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_16/Task_16.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Напишите функцию BuildMapValuesSet, принимающую на вход словарь map и возвращающую множество значений этого словаря: 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | std::set BuildMapValuesSet (const std::map& m) 11 | { 12 | std::set result; 13 | for (const auto& item : m) 14 | { 15 | result.insert(item.second); 16 | } 17 | 18 | return result; 19 | } 20 | 21 | int main() 22 | { 23 | std::set values = BuildMapValuesSet( 24 | { 25 | {1,"odd"}, 26 | {2,"even"}, 27 | {3,"odd"}, 28 | {4,"even"}, 29 | {5,"odd"} 30 | }); 31 | 32 | for (const auto& value : values) 33 | { 34 | std::cout << value << std::endl; 35 | } 36 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_17/Task_17.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Два слова называются синонимами друг друга, если они имеют похожие значения. Реализуйте следующие операции над словарём синонимов: 3 | * 4 | * ADD word1 word2 — добавить в словарь пару синонимов (word1, word2). 5 | * COUNT word — узнать количество синонимов слова word. 6 | * CHECK word1 word2 — проверить, являются ли слова word1 и word2 синонимами. 7 | * Слова word1 и word2 считаются синонимами, если среди запросов ADD был хотя бы один запрос ADD word1 word2 или ADD word2 word1. 8 | * 9 | * Формат ввода 10 | * Сначала вводится количество запросов Q, затем Q строк с описаниями запросов. 11 | * Гарантируется, что в каждом запросе CHECK и ADD слова word1 и word2 различны. 12 | * Все слова состоят лишь из латинских букв, цифр и символов подчёркивания. 13 | * 14 | * Формат вывода 15 | * Для каждого запроса в соответствующей строке выведите ответ на него: 16 | * В ответ на запрос COUNT word выведите единственное целое число — количество синонимов слова word. 17 | * В ответ на запрос CHECK word1 word2 выведите строку YES, если word1 и word2 являются синонимами, и NO в противном случае. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | int main() 26 | { 27 | std::map > list_synonyms; 28 | 29 | int command_count; 30 | std::cin >> command_count; 31 | 32 | for (int i = 0; i < command_count; ++i) 33 | { 34 | std::string command; 35 | std::cin >> command; 36 | 37 | if (command == "ADD") 38 | { 39 | std::string first_word, second_word; 40 | std::cin >> first_word >> second_word; 41 | 42 | list_synonyms[first_word].insert(second_word); 43 | list_synonyms[second_word].insert(first_word); 44 | 45 | continue; 46 | } 47 | 48 | if(command == "COUNT") 49 | { 50 | std::string word; 51 | std::cin >> word; 52 | 53 | if (list_synonyms.count(word) == 1) 54 | std::cout << list_synonyms[word].size() << std::endl; 55 | else 56 | std::cout << "0" << std::endl; 57 | 58 | continue; 59 | } 60 | 61 | if(command == "CHECK") 62 | { 63 | std::string first_word, second_word; 64 | std::cin >> first_word >> second_word; 65 | 66 | if(list_synonyms.count(first_word) == 1) 67 | { 68 | if (list_synonyms[first_word].count(second_word) == 1) 69 | std::cout << "YES" << std::endl; 70 | else 71 | std::cout << "NO" << std::endl; 72 | } 73 | else 74 | { 75 | std::cout << "NO" << std::endl; 76 | } 77 | } 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_18/Task_18.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * В этой задаче вам нужно присваивать номера автобусным маршрутам. 3 | * 4 | * А именно, для каждого маршрута, заданного множеством названий остановок, нужно либо выдать новый номер (первому маршруту — 1, второму — 2 и т. д.), 5 | * либо вернуть номер существующего маршрута, которому соответствует такое множество остановок. 6 | * 7 | * В отличие от задачи «Автобусные остановки — 2», наборы остановок, 8 | * которые можно получить друг из друга перестановкой элементов или добавлением/удалением повторяющихся, следует считать одинаковыми. 9 | * 10 | * Формат ввода 11 | * Сначала вводится количество запросов Q, затем Q описаний запросов. 12 | * 13 | * Каждый запрос представляет собой положительное количество остановок N, за которым следуют разделённые пробелом N названий остановок соответствующего маршрута (не обязательно различных). 14 | * Названия остановок состоят лишь из латинских букв и символов подчёркивания. 15 | * 16 | * Формат вывода 17 | * Выведите ответ на каждый запрос в отдельной строке. 18 | * 19 | * Если маршрут с данным набором остановок уже существует, в ответ на соответствующий запрос выведите Already exists for i, где i — номер маршрута с таким набором остановок. 20 | * В противном случае нужно выделить введённому набору остановок новый номер i и вывести его в формате New bus i. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | std::map, int> list_bus_stops; 31 | int command_count, number_route = 0; 32 | 33 | std::cin >> command_count; 34 | 35 | for (int i = 0; i < command_count; ++i) 36 | { 37 | int stops_count; 38 | std::set stops; 39 | 40 | std::cin >> stops_count; 41 | 42 | for (int j = 0; j < stops_count; ++j) 43 | { 44 | std::string stop_name; 45 | std::cin >> stop_name; 46 | 47 | stops.insert(stop_name); 48 | } 49 | 50 | if(list_bus_stops.count(stops) == 1) 51 | { 52 | std::cout << "Already exists for " << list_bus_stops[stops] << std::endl; 53 | } 54 | else 55 | { 56 | list_bus_stops[stops] = ++number_route; 57 | std::cout << "New bus " << number_route << std::endl; 58 | } 59 | 60 | stops.clear(); 61 | } 62 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Напишите функцию, которая 3 | * называется IsPalindrom 4 | * возвращает bool 5 | * принимает параметр типа string и возвращает, является ли переданная строка палиндромом 6 | * Палиндром - это слово или фраза, которые одинаково читаются слева направо и справа налево. 7 | * Пустая строка является палиндромом. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | bool IsPalindrom (string word) 16 | { 17 | for (size_t i = 0; i < word.size() / 2; i++) 18 | { 19 | if (word[i] != word[word.size() - i - 1]) 20 | return false; 21 | } 22 | return true; 23 | } 24 | 25 | int main() 26 | { 27 | string word; 28 | cin >> word; 29 | cout << IsPalindrom(word); 30 | 31 | return 0; 32 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Напишите функцию, которая 3 | * называется PalindromFilter 4 | * возвращает vector 5 | * принимает vector words и int minLength и возвращает все строки из вектора words, которые являются палиндромами и имеют длину не меньше minLength 6 | * Входной вектор содержит не более 100 строк, длина каждой строки не больше 100 символов. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | bool IsPalindrom(string word) 16 | { 17 | for (size_t i = 0; i < word.size() / 2; i++) 18 | { 19 | if (word[i] != word[word.size() - i - 1]) 20 | return false; 21 | } 22 | return true; 23 | } 24 | 25 | vector PalindromFilter (vector words, size_t minLength) 26 | { 27 | vector newVector; 28 | for(auto w : words) 29 | { 30 | if(IsPalindrom(w) && w.length() >= minLength) 31 | { 32 | newVector.push_back(w); 33 | } 34 | } 35 | return newVector; 36 | } 37 | 38 | int main() 39 | { 40 | vector test = { "water", "madam", "aba", "weew", "qwerty", "asdffdsa" }; 41 | vector simple = PalindromFilter(test, 4); 42 | 43 | for (auto w : simple) 44 | cout << w << " "; 45 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_4/Task_4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Напишите функцию UpdateIfGreater, которая принимает два целочисленных аргумента: first и second. 3 | * Если first оказался больше second, Ваша функция должна записывать в second значение параметра first. 4 | * При этом изменение параметра second должно быть видно на вызывающей стороне. 5 | */ 6 | 7 | #include 8 | 9 | using namespace std; 10 | 11 | void UpdateIfGreater (const int& number1, int& number2) 12 | { 13 | if (number1 > number2) 14 | number2 = number1; 15 | } 16 | 17 | int main() 18 | { 19 | int number1, number2; 20 | cin >> number1 >> number2; 21 | UpdateIfGreater(number1, number2); 22 | cout << number1 << " " << number2 << endl; 23 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_5/Task_5.cpp: -------------------------------------------------------------------------------- 1 | /* Напишите функцию MoveStrings, которая принимает два вектора строк, source и destination, и дописывает все строки из первого вектора в конец второго. 2 | * После выполнения функции вектор source должен оказаться пустым. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | void MoveStrings(vector& source, vector& destination) 12 | { 13 | for (auto w : source) 14 | destination.push_back(w); 15 | 16 | source.clear(); 17 | } 18 | 19 | int main() 20 | { 21 | vector first = { "qwe", "rty", "asd", "fgh" }; 22 | vector second = { "keyboard: " }; 23 | MoveStrings(first, second); 24 | 25 | cout << "first - "; 26 | for (auto w : first) 27 | cout << w ; 28 | 29 | cout << endl; 30 | 31 | cout << "second - "; 32 | for (auto w : second) 33 | cout << w; 34 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_6/Task_6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Реализуйте функцию void Reverse(vector& v), которая переставляет элементы вектора в обратном порядке. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | void ReverseV1 (vector& v) 12 | { 13 | for (int i = 0; i < v.size() / 2 ; i++) 14 | { 15 | int buff = v[i]; 16 | v[i] = v[v.size() - i - 1]; 17 | v[v.size() - i - 1] = buff; 18 | } 19 | } 20 | 21 | void ReverseV2 (vector& v) 22 | { 23 | vector buff; 24 | for (int i = v.size() - 1; i >= 0; i--) 25 | buff.push_back(v[i]); 26 | v.clear(); 27 | v = buff; 28 | } 29 | 30 | int main() 31 | { 32 | vector test = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; 33 | ReverseV1 (test); 34 | 35 | for (auto n : test) 36 | cout << n << " "; 37 | 38 | cout << endl; 39 | 40 | ReverseV2(test); 41 | 42 | for (auto n : test) 43 | cout << n << " "; 44 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_7/Task_7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Реализуйте функцию vector Reversed(const vector& v), возвращающую копию вектора v, в которой числа переставлены в обратном порядке. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | vector Reversed(const vector& v) 12 | { 13 | vector buff; 14 | for (int i = v.size() - 1; i >= 0; i--) 15 | buff.push_back(v[i]); 16 | return buff; 17 | } 18 | 19 | int main() 20 | { 21 | vector test = { 1, 5, 3, 4, 2 }; 22 | vector simple = Reversed(test); 23 | 24 | for (auto n : simple) 25 | cout << n << " "; 26 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_8/Task_8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Даны значения температуры, наблюдавшиеся в течение N подряд идущих дней. 3 | * Найдите номера дней (в нумерации с нуля) со значением температуры выше среднего арифметического за все N дней. 4 | * Гарантируется, что среднее арифметическое значений температуры является целым числом. 5 | * 6 | * Формат ввода 7 | * Вводится число N, затем N неотрицательных целых чисел — значения температуры в 0-й, 1-й, ... (N−1)-й день. 8 | * 9 | * Формат вывода 10 | * Первое число K — количество дней, значение температуры в которых выше среднего арифметического. 11 | * Затем K целых чисел — номера этих дней. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | int main() 21 | { 22 | int length; 23 | int sum = 0; 24 | int days = 0; 25 | cin >> length; 26 | 27 | vector temperatures(length); 28 | 29 | for (int& temperature : temperatures) 30 | { 31 | cin >> temperature; 32 | sum += temperature; 33 | } 34 | 35 | int average = sum / length; 36 | 37 | for (int temperature : temperatures) 38 | if (temperature > average) 39 | days++; 40 | 41 | cout << days << endl; 42 | 43 | for (int i = 0; i < temperatures.size(); i++) 44 | if (temperatures[i] > average) 45 | cout << i << " "; 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Task_9/Task_9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Люди стоят в очереди, но никогда не уходят из её начала, зато могут приходить в конец и уходить оттуда. 3 | * Более того, иногда некоторые люди могут прекращать и начинать беспокоиться из-за того, что очередь не продвигается. 4 | * 5 | * Реализуйте обработку следующих операций над очередью: 6 | * WORRY i: пометить i-го человека с начала очереди (в нумерации с 0) как беспокоящегося; 7 | * QUIET i: пометить i-го человека как успокоившегося; 8 | * COME k: добавить k спокойных человек в конец очереди; 9 | * COME -k: убрать k человек из конца очереди; 10 | * WORRY_COUNT: узнать количество беспокоящихся людей в очереди. 11 | * Изначально очередь пуста. 12 | * 13 | * Формат ввода 14 | * Количество операций Q, затем описания операций. 15 | * 16 | * Для каждой операции WORRY i и QUIET i гарантируется, что человек с номером i существует в очереди на момент операции. 17 | * Для каждой операции COME -k гарантируется, что k не больше текущего размера очереди. 18 | * 19 | * Формат вывода 20 | * Для каждой операции WORRY_COUNT выведите одно целое число — количество беспокоящихся людей в очереди. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | using namespace std; 29 | 30 | int main() 31 | { 32 | int comands_count; 33 | cin >> comands_count; 34 | 35 | vector queue; 36 | for (int i = 0; i < comands_count; i++) 37 | { 38 | string command; 39 | cin >> command; 40 | 41 | if (command == "COME") 42 | { 43 | int length; 44 | cin >> length; 45 | for (int j = 0; j < abs(length); j++) 46 | { 47 | if (length > 0) 48 | queue.push_back(false); 49 | else 50 | if (length < 0) 51 | queue.pop_back(); 52 | } 53 | } 54 | 55 | if (command == "WORRY") 56 | { 57 | int index; 58 | cin >> index; 59 | queue[index] = true; 60 | } 61 | 62 | if (command == "QUIET") 63 | { 64 | int index; 65 | cin >> index; 66 | queue[index] = false; 67 | } 68 | 69 | if (command == "WORRY_COUNT") 70 | { 71 | int worryCount = 0; 72 | for (bool f : queue) 73 | if (f) 74 | worryCount++; 75 | cout << worryCount << endl; 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Updated/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Напишите функцию, которая 3 | * называется IsPalindrom 4 | * возвращает bool 5 | * принимает параметр типа string и возвращает, является ли переданная строка палиндромом 6 | * Палиндром - это слово или фраза, которые одинаково читаются слева направо и справа налево. 7 | * Пустая строка является палиндромом. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | bool IsPalindrom(const std::string& word) 14 | { 15 | return std::equal(word.begin(), word.begin() + (word.size() / 2), word.rbegin()); 16 | } 17 | 18 | int main() 19 | { 20 | std::string word; 21 | std::cin >> word; 22 | std::cout << IsPalindrom(word); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /White Belt/Week_2/Updated/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Напишите функцию, которая 3 | * называется PalindromFilter 4 | * возвращает vector 5 | * принимает vector words и int minLength и возвращает все строки из вектора words, которые являются палиндромами и имеют длину не меньше minLength 6 | * Входной вектор содержит не более 100 строк, длина каждой строки не больше 100 символов. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | bool IsPalindrom(const std::string& word) 14 | { 15 | return std::equal(word.begin(), word.begin() + (word.size() / 2), word.rbegin()); 16 | } 17 | 18 | std::vector PalindromFilter (std::vector words, size_t minLength) 19 | { 20 | const auto it = std::remove_if(words.begin(), words.end(), 21 | [minLength](const std::string& word) 22 | { 23 | return word.size() < minLength || !IsPalindrom(word); 24 | }); 25 | 26 | words.erase(it, words.end()); 27 | 28 | return words; 29 | } 30 | 31 | int main() 32 | { 33 | std::vector test = { "water", "madam", "aba", "weew", "qwerty", "asdffdsa" }; 34 | std::vector simple = PalindromFilter(test, 4); 35 | 36 | for (const auto& word : simple) 37 | { 38 | std::cout << word << " "; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /White Belt/Week_2/Updated/Task_5.cpp: -------------------------------------------------------------------------------- 1 | /* Напишите функцию MoveStrings, которая принимает два вектора строк, source и destination, и дописывает все строки из первого вектора в конец второго. 2 | * После выполнения функции вектор source должен оказаться пустым. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | void MoveStrings(std::vector& source, std::vector& destination) 9 | { 10 | destination.reserve(destination.size() + source.size()); 11 | std::move(source.begin(), source.end(), std::back_inserter(destination)); 12 | source.clear(); 13 | } 14 | 15 | int main() 16 | { 17 | std::vector first = { "qwe", "rty", "asd", "fgh" }; 18 | std::vector second = { "keyboard: " }; 19 | MoveStrings(first, second); 20 | 21 | std::cout << "first - "; 22 | for (const auto& word : first) 23 | { 24 | std::cout << word ; 25 | } 26 | 27 | std::cout << std::endl; 28 | 29 | std::cout << "second - "; 30 | for (const auto& word : second) 31 | { 32 | std::cout << word; 33 | } 34 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Updated/Task_6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Реализуйте функцию void Reverse(vector& v), которая переставляет элементы вектора в обратном порядке. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void Reverse(std::vector& vector) 10 | { 11 | std::reverse(vector.begin(), vector.end()); 12 | } 13 | 14 | int main() 15 | { 16 | std::vector test = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; 17 | Reverse (test); 18 | 19 | for (auto n : test) 20 | { 21 | std::cout << n << " "; 22 | } 23 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Updated/Task_7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Реализуйте функцию vector Reversed(const vector& v), возвращающую копию вектора v, в которой числа переставлены в обратном порядке. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | std::vector Reversed(const std::vector& vector) 9 | { 10 | return { vector.rbegin(), vector.rend() }; 11 | } 12 | 13 | int main() 14 | { 15 | const std::vector test = { 1, 5, 3, 4, 2 }; 16 | const std::vector simple = Reversed(test); 17 | 18 | for (auto n : simple) 19 | { 20 | std::cout << n << " "; 21 | } 22 | } -------------------------------------------------------------------------------- /White Belt/Week_2/Updated/Task_9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Люди стоят в очереди, но никогда не уходят из её начала, зато могут приходить в конец и уходить оттуда. 3 | * Более того, иногда некоторые люди могут прекращать и начинать беспокоиться из-за того, что очередь не продвигается. 4 | * 5 | * Реализуйте обработку следующих операций над очередью: 6 | * WORRY i: пометить i-го человека с начала очереди (в нумерации с 0) как беспокоящегося; 7 | * QUIET i: пометить i-го человека как успокоившегося; 8 | * COME k: добавить k спокойных человек в конец очереди; 9 | * COME -k: убрать k человек из конца очереди; 10 | * WORRY_COUNT: узнать количество беспокоящихся людей в очереди. 11 | * Изначально очередь пуста. 12 | * 13 | * Формат ввода 14 | * Количество операций Q, затем описания операций. 15 | * 16 | * Для каждой операции WORRY i и QUIET i гарантируется, что человек с номером i существует в очереди на момент операции. 17 | * Для каждой операции COME -k гарантируется, что k не больше текущего размера очереди. 18 | * 19 | * Формат вывода 20 | * Для каждой операции WORRY_COUNT выведите одно целое число — количество беспокоящихся людей в очереди. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | int main() 28 | { 29 | size_t command_count; 30 | std::cin >> command_count; 31 | std::vector queue; 32 | 33 | for(size_t i = 0; i < command_count; ++i) 34 | { 35 | std::string command; 36 | std::cin >> command; 37 | 38 | if(command == "COME") 39 | { 40 | int count; 41 | std::cin >> count; 42 | queue.resize(queue.size() + count); 43 | } 44 | else if(command == "WORRY" || command == "QUIET") 45 | { 46 | size_t index; 47 | std::cin >> index; 48 | queue[index] = (command == "WORRY"); 49 | } 50 | else if(command == "WORRY_COUNT") 51 | { 52 | std::cout << std::count(queue.begin(), queue.end(), true) << std::endl; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /White Belt/Week_3/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Условие 3 | 4 | В стандартном потоке дана одна строка, состоящая из N + 1 целых чисел. 5 | Первым числом идёт само число N. Далее следуют ещё N чисел, обозначим их за массив A. 6 | Между собой числа разделены пробелом. 7 | 8 | Отсортируйте массив А по модулю и выведите его в стандартный поток. 9 | 10 | Ограничения 11 | 0 <= N <= 1000 12 | -1000000 <= A[i] <= 1000000 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | void PrintVector(const std::vector& vec) 20 | { 21 | for (const int& item : vec) 22 | { 23 | std::cout << item << " "; 24 | } 25 | std::cout << std::endl; 26 | } 27 | 28 | int main() 29 | { 30 | size_t length; 31 | std::cin >> length; 32 | std::vector mass(length); 33 | 34 | for (size_t i = 0; i < length; i++) 35 | { 36 | int number; 37 | std::cin >> number; 38 | mass[i] = number; 39 | } 40 | 41 | std::sort(std::begin(mass), std::end(mass), [](int& x, int& y) 42 | { 43 | return abs(x) < abs(y); 44 | }); 45 | 46 | PrintVector(mass); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /White Belt/Week_3/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Условие 3 | В стандартном потоке дана одна строка, состоящая из числа N и следующих за ним N строк S. Между собой число и строки разделены пробелом. 4 | 5 | Отсортируйте строки S в лексикографическом порядке по возрастанию, игнорируя регистр букв, и выведите их в стандартный поток вывода. 6 | 7 | Ограничения 8 | 0 <= N <= 1000 9 | 1 <= |S| <= 15 10 | Каждая строка S[i] может состоять из следующих символов: [0-9,a-z,A-Z] 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | void PrintVector(const std::vector& vec) 19 | { 20 | for (const std::string& item : vec) 21 | { 22 | std::cout << item << ' '; 23 | } 24 | std::cout << std::endl; 25 | } 26 | 27 | int main() 28 | { 29 | int length; 30 | std::cin >> length; 31 | 32 | std::vector mass(length); 33 | 34 | for (std::string& symbol : mass) 35 | { 36 | std::string word; 37 | std::cin >> word; 38 | symbol = word; 39 | } 40 | 41 | std::sort(std::begin(mass), std::end(mass), [](std::string x, std::string y) 42 | { 43 | for (char& symbol : x) 44 | { 45 | symbol = tolower(symbol); 46 | } 47 | 48 | for (char& symbol : y) 49 | { 50 | symbol = tolower(symbol); 51 | } 52 | 53 | return x < y; 54 | }); 55 | 56 | PrintVector(mass); 57 | 58 | return 0; 59 | } -------------------------------------------------------------------------------- /White Belt/Week_3/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | //Реализуйте класс, поддерживающий набор строк в отсортированном порядке. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class SortedStrings 9 | { 10 | public: 11 | void AddString(const std::string& word) 12 | { 13 | sorted_string.push_back(word); 14 | } 15 | std::vector GetSortedStrings() 16 | { 17 | std::sort(std::begin(sorted_string), std::end(sorted_string)); 18 | return sorted_string; 19 | } 20 | private: 21 | std::vector sorted_string; 22 | }; 23 | 24 | void PrintSortedStrings(SortedStrings& strings) 25 | { 26 | for (const std::string& s : strings.GetSortedStrings()) 27 | { 28 | std::cout << s << " "; 29 | } 30 | std::cout << std::endl; 31 | } 32 | 33 | int main() 34 | { 35 | SortedStrings strings; 36 | strings.AddString("first"); 37 | strings.AddString("second"); 38 | strings.AddString("third"); 39 | PrintSortedStrings(strings); 40 | 41 | strings.AddString("second"); 42 | PrintSortedStrings(strings); 43 | 44 | return 0; 45 | } -------------------------------------------------------------------------------- /White Belt/Week_3/Task_6/Task_6.cpp: -------------------------------------------------------------------------------- 1 | // Task_6.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. 2 | // 3 | 4 | /* 5 | Реализуйте класс ReversibleString, 6 | хранящий строку и поддерживающий методы Reverse для 7 | переворота строкии ToString для получения строки. 8 | */ 9 | #include 10 | #include 11 | #include 12 | 13 | class ReversibleString 14 | { 15 | public: 16 | ReversibleString (const std::string& str) 17 | { 18 | line = str; 19 | } 20 | ReversibleString() 21 | { 22 | line = ""; 23 | } 24 | void Reverse() 25 | { 26 | std::reverse(std::begin(line), std::end(line)); 27 | } 28 | std::string ToString() const 29 | { 30 | return line; 31 | } 32 | private: 33 | std::string line; 34 | }; 35 | int main() 36 | { 37 | ReversibleString s("live"); 38 | s.Reverse(); 39 | std::cout << s.ToString() << std::endl; 40 | 41 | s.Reverse(); 42 | const ReversibleString& s_ref = s; 43 | std::string tmp = s_ref.ToString(); 44 | std::cout << tmp << std::endl; 45 | 46 | ReversibleString empty; 47 | std::cout << '"' << empty.ToString() << '"' << std::endl; 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /White Belt/Week_3/Task_8/Task_8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Определите тип Incognizable, для которого следующий код будет корректен: 3 | */ 4 | 5 | #include 6 | 7 | class Incognizable 8 | { 9 | public: 10 | Incognizable() 11 | { 12 | x = 0; 13 | y = 0; 14 | }; 15 | 16 | Incognizable(int a) 17 | { 18 | x = a; 19 | y = 0; 20 | }; 21 | 22 | Incognizable(int a, int b) 23 | { 24 | x = a; 25 | y = b; 26 | }; 27 | 28 | private: 29 | int x; 30 | int y; 31 | }; 32 | int main() 33 | { 34 | Incognizable a; 35 | Incognizable b = {}; 36 | Incognizable c = { 0 }; 37 | Incognizable d = { 0, 1 }; 38 | } -------------------------------------------------------------------------------- /White Belt/Week_4/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Дана структура LectureTitle: 3 | struct LectureTitle { 4 | string specialization; 5 | string course; 6 | string week; 7 | }; 8 | Допишите конструктор и структуры Specialization, Course, Week так, чтобы объект LectureTitle можно было создать с помощью кода 9 | LectureTitle title( 10 | Specialization("C++"), 11 | Course("White belt"), 12 | Week("4th") 13 | ); 14 | но нельзя было с помощью следующих фрагментов кода: 15 | 16 | LectureTitle title("C++", "White belt", "4th"); 17 | 18 | LectureTitle title(string("C++"), string("White belt"), string("4th")); 19 | 20 | LectureTitle title = {"C++", "White belt", "4th"}; 21 | 22 | LectureTitle title = {{"C++"}, {"White belt"}, {"4th"}}; 23 | 24 | LectureTitle title( 25 | Course("White belt"), 26 | Specialization("C++"), 27 | Week("4th") 28 | ); 29 | 30 | LectureTitle title( 31 | Specialization("C++"), 32 | Week("4th"), 33 | Course("White belt") 34 | ); 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | struct Specialization 41 | { 42 | explicit Specialization(const std::string& new_value) 43 | { 44 | value = new_value; 45 | } 46 | std::string value; 47 | }; 48 | 49 | struct Course 50 | { 51 | explicit Course(const std::string& new_value) 52 | { 53 | value = new_value; 54 | } 55 | std::string value; 56 | }; 57 | 58 | struct Week 59 | { 60 | explicit Week(const std::string& new_value) 61 | { 62 | value = new_value; 63 | } 64 | std::string value; 65 | }; 66 | 67 | struct LectureTitle 68 | { 69 | explicit LectureTitle(const Specialization& spec_name, const Course& course_name, const Week& week_name) 70 | { 71 | specialization = spec_name.value; 72 | course = course_name.value; 73 | week = week_name.value; 74 | } 75 | std::string specialization; 76 | std::string course; 77 | std::string week; 78 | }; 79 | 80 | int main() 81 | { 82 | LectureTitle title( 83 | Specialization("C++"), 84 | Course("White belt"), 85 | Week("4th") 86 | ); 87 | } 88 | -------------------------------------------------------------------------------- /White Belt/Week_4/Task_14/Task_14.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Напишите функцию 3 | void EnsureEqual(const string& left, const string& right); 4 | 5 | В случае, если строка left не равна строке right, функция должна выбрасывать исключение runtime_error 6 | с содержанием " != ", где и - строки, которые хранятся в переменных left и right соответственно. 7 | Обратите внимание, что вокруг знака неравенства в строке, которая помещается в исключение, должно быть ровно по одному пробелу. 8 | 9 | Если left == right, функция должна корректно завершаться. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | void EnsureEqual(const std::string& left, const std::string right) 17 | { 18 | if (left != right) 19 | throw std::runtime_error(left + " != " + right); 20 | } 21 | 22 | int main() 23 | { 24 | try 25 | { 26 | EnsureEqual("C++ White", "C++ White"); 27 | EnsureEqual("C++ White", "C++ Yellow"); 28 | } 29 | catch (std::runtime_error& error) 30 | { 31 | std::cout << error.what() << std::endl; 32 | } 33 | 34 | return 0; 35 | } -------------------------------------------------------------------------------- /White Belt/Week_4/Task_4/Task_4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * В этом задании вам предстоит написать две небольшие программы. 3 | * Каждый пункт - отдельная задача, решение отправляйте в поле с соответствующим номером. 4 | * 5 | * Часть 1 6 | * Ваша программа должна считать содержимое файла input.txt и напечатать его на экран без изменений. 7 | * Гарантируется, что содержимое файла input.txt заканчивается переводом строки. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | int main() 15 | { 16 | std::ifstream input("input.txt"); 17 | 18 | if (input.is_open()) 19 | { 20 | std::string line; 21 | while (std::getline(input, line)) 22 | { 23 | std::cout << line << std::endl; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /White Belt/Week_4/Task_4/input.txt: -------------------------------------------------------------------------------- 1 | Keep calm 2 | and 3 | learn C++ -------------------------------------------------------------------------------- /White Belt/Week_4/Task_5/Task_5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * В этом задании вам предстоит написать две небольшие программы. 3 | * Каждый пункт - отдельная задача, решение отправляйте в поле с соответствующим номером. 4 | * 5 | * Часть 2 6 | * Снова считайте все содержимое файла input.txt, но на этот раз выведите его в файл output.txt. 7 | * Точно так же гарантируется, что содержимое файла input.txt заканчивается переводом строки. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | int main() 14 | { 15 | std::fstream input("input.txt"); 16 | std::ofstream output("output.txt"); 17 | 18 | if(input) 19 | { 20 | std::string line; 21 | while (std::getline(input, line)) 22 | { 23 | output << line << std::endl; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /White Belt/Week_4/Task_5/input.txt: -------------------------------------------------------------------------------- 1 | Keep calm 2 | and 3 | learn C++ -------------------------------------------------------------------------------- /White Belt/Week_4/Task_5/output.txt: -------------------------------------------------------------------------------- 1 | Keep calm 2 | and 3 | learn C++ -------------------------------------------------------------------------------- /White Belt/Week_4/Task_6/Task_6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В файле input.txt записаны вещественные числа, по одному на строчку. 3 | На стандартный вывод напечатайте эти числа в том же порядке, по одному на строке, но сделайте так, 4 | чтобы у каждого из них было ровно три знака после десятичной точки 5 | (округление производится по стандартным правилам, т.е. 0.1234 округляется до 0.123, а 0.1235 до 0.124). 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int main() 13 | { 14 | std::fstream input("input.txt"); 15 | if (input.is_open()) 16 | { 17 | double number = 0; 18 | std::cout << std::fixed << std::setprecision(3); 19 | while (input >> number) 20 | { 21 | std::cout << number << std::endl; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /White Belt/Week_4/Task_6/input.txt: -------------------------------------------------------------------------------- 1 | 5 2 | 0.34567 3 | 10.4 4 | 3.33353 5 | 3.333 6 | 3.3 -------------------------------------------------------------------------------- /White Belt/Week_4/Task_7/Task_7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В первой строке файла input.txt записаны два числа N и M. 3 | Далее в файле находится таблица из N строк и M столбцов, представленная в формате CSV (comma-separated values). 4 | Такой формат часто используется для текстового представления таблиц с данными 5 | в файле несколько строк, значения из разных ячеек внутри строки отделены друг от друга запятыми. 6 | Ваша задача — вывести данные на экран в виде таблицы, размер ячейки которой равен 10, соседние ячейки отделены друг от друга пробелом. 7 | После последней ячейки пробела быть не должно. 8 | Гарантируется, что в таблице будет ровно N строк и M столбцов, значение каждой из ячеек — целое число. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | int main() 16 | { 17 | std::ifstream input("input.txt"); 18 | if (input.is_open()) 19 | { 20 | int rows, columns; 21 | 22 | input >> rows; 23 | input.ignore(1); 24 | input >> columns; 25 | 26 | for (int i = 0; i < rows; ++i) 27 | { 28 | for (int j = 0; j < columns; ++j) 29 | { 30 | int number; 31 | input >> number; 32 | input.ignore(1); 33 | 34 | if (j != columns - 1) 35 | { 36 | std::cout << std::setw(10) << number << ' '; 37 | } 38 | else 39 | { 40 | std::cout << std::setw(10) << number << std::endl; 41 | } 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /White Belt/Week_4/Task_7/input.txt: -------------------------------------------------------------------------------- 1 | 2 3 2 | 100000000,2,3 3 | 4,5,6 -------------------------------------------------------------------------------- /White Belt/Week_4/Task_8/Task_8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Определите структуру «Студент» со следующими полями: 3 | имя, фамилия, день, месяц и год рождения. 4 | Создайте вектор из таких структур, заполните его из входных данных и затем по запросам выведите нужные поля. 5 | 6 | Формат ввода 7 | 8 | Первая строка содержит одно целое число N от 0 до 10000 — число студентов. 9 | 10 | Далее идут N строк, каждая из которых содержит две строки длиной от 1 до 15 символов — имя и фамилию очередного студента, 11 | и три целых числа от 0 до 1000000000 — день, месяц и год рождения. 12 | 13 | Следующая строка содержит одно целое число M от 0 до 10000 — число запросов. 14 | 15 | Следующие M строк содержат строку длиной от 1 до 15 символов — запрос, 16 | и целое число от 0 до 1000000000 — номер студента (нумерация начинается с 1). 17 | 18 | Формат вывода 19 | 20 | Для запроса вида name K, где K от 1 до N, выведите через пробел имя и фамилию K-го студента. 21 | 22 | Для запроса вида date K, где K от 1 до N, выведите через точку день, месяц и год рождения K-го студента. 23 | 24 | Для остальных запросов выведите bad request. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | struct Student 32 | { 33 | std::string first_name; 34 | std::string last_name; 35 | int birthday; 36 | int birth_month; 37 | int birth_year; 38 | 39 | void GetFullName() const 40 | { 41 | std::cout << first_name << ' ' << last_name << std::endl; 42 | } 43 | 44 | void GetBirthDay() const 45 | { 46 | std::cout << birthday << '.' << birth_month << '.' << birth_year << std::endl; 47 | } 48 | }; 49 | 50 | int main() 51 | { 52 | int count_student; 53 | std::cin >> count_student; 54 | 55 | std::vector students; 56 | 57 | for (int i = 0; i < count_student; ++i) 58 | { 59 | std::string new_first_name, new_last_name; 60 | int new_birthday, new_birth_month, new_birth_year; 61 | 62 | std::cin >> new_first_name >> new_last_name >> new_birthday >> new_birth_month >> new_birth_year; 63 | 64 | students.emplace_back(Student{ new_first_name, new_last_name, new_birthday, new_birth_month, new_birth_year }); 65 | } 66 | 67 | int count_command; 68 | std::cin >> count_command; 69 | 70 | for (int i = 0; i < count_command; ++i) 71 | { 72 | std::string command; 73 | int student; 74 | std::cin >> command >> student; 75 | 76 | if (command == "name" && student > 0 && student <= students.size()) 77 | { 78 | students[--student].GetFullName(); 79 | continue; 80 | } 81 | 82 | if (command == "date" && student > 0 && student <= students.size()) 83 | { 84 | students[--student].GetBirthDay(); 85 | continue; 86 | } 87 | 88 | std::cout << "bad request" << std::endl; 89 | } 90 | } -------------------------------------------------------------------------------- /White Belt/Week_5 (Final_project)/Updated/Database.cpp: -------------------------------------------------------------------------------- 1 | #include "Database.h" 2 | 3 | #include 4 | #include 5 | 6 | void Database::AddEvent(const Date& date, const std::string& event) 7 | { 8 | if (!event.empty()) 9 | { 10 | db_[date].insert(event); 11 | } 12 | } 13 | 14 | bool Database::DeleteEvent(const Date& date, const std::string& event) 15 | { 16 | return db_[date].erase(event); 17 | } 18 | 19 | int Database::DeleteDate(const Date& date) 20 | { 21 | const int count_event = db_[date].size(); 22 | db_.erase(date); 23 | 24 | return count_event; 25 | } 26 | 27 | std::set Database::Find(const Date& date) const 28 | { 29 | if (db_.count(date)) 30 | { 31 | return db_.at(date); 32 | } 33 | return std::set(); 34 | } 35 | 36 | void Database::Print() const 37 | { 38 | for (const auto& [date, events] : db_) 39 | { 40 | bool is_first = true; 41 | for (const auto& event : events) 42 | { 43 | std::cout << std::setw(4) << std::setfill('0') << date.GetYear() << '-' 44 | << std::setw(2) << std::setfill('0') << date.GetMonth() << '-' 45 | << std::setw(2) << std::setfill('0') << date.GetDay() << ' ' 46 | << event << std::endl; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /White Belt/Week_5 (Final_project)/Updated/Database.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Date.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class Database 10 | { 11 | public: 12 | Database() = default; 13 | 14 | void AddEvent(const Date& date, const std::string& event); 15 | bool DeleteEvent(const Date& date, const std::string& event); 16 | int DeleteDate(const Date& date); 17 | 18 | std::set Find(const Date& date) const; 19 | void Print() const; 20 | 21 | private: 22 | std::map> db_; 23 | }; 24 | -------------------------------------------------------------------------------- /White Belt/Week_5 (Final_project)/Updated/Date.cpp: -------------------------------------------------------------------------------- 1 | #include "Date.h" 2 | 3 | #include 4 | #include 5 | 6 | Date::Date(const int year, const int month, const int day) 7 | { 8 | year_ = year; 9 | 10 | if (month <= 0 || month > 12) 11 | { 12 | throw std::invalid_argument("Month value is invalid: " + std::to_string(month)); 13 | } 14 | month_ = month; 15 | 16 | if (day <= 0 || day > 31) 17 | { 18 | throw std::invalid_argument("Day value is invalid: " + std::to_string(day)); 19 | } 20 | day_ = day; 21 | 22 | } 23 | 24 | int Date::GetYear() const 25 | { 26 | return year_; 27 | } 28 | 29 | int Date::GetMonth() const 30 | { 31 | return month_; 32 | } 33 | 34 | int Date::GetDay() const 35 | { 36 | return day_; 37 | } 38 | 39 | int ReadInt(std::stringstream& ss, bool& flag) 40 | { 41 | int number{}; 42 | flag = flag && (ss >> number); 43 | return number; 44 | } 45 | 46 | void CheckSymbol(std::stringstream& ss, bool& flag) 47 | { 48 | flag = flag && (ss.peek() == '-'); 49 | ss.ignore(1); 50 | } 51 | 52 | bool operator<(const Date& lhs, const Date& rhs) 53 | { 54 | return std::tuple(lhs.GetYear(), lhs.GetMonth(), lhs.GetDay()) < 55 | std::tuple(rhs.GetYear(), rhs.GetMonth(), rhs.GetDay()); 56 | } 57 | 58 | std::istream& operator>>(std::istream& is, Date& date) 59 | { 60 | std::string date_string; 61 | is >> date_string; 62 | std::stringstream ss(date_string); 63 | bool is_correct = true; 64 | 65 | const int year = ReadInt(ss, is_correct); 66 | CheckSymbol(ss, is_correct); 67 | 68 | const int month = ReadInt(ss, is_correct); 69 | CheckSymbol(ss, is_correct); 70 | 71 | const int day = ReadInt(ss, is_correct); 72 | 73 | if (!is_correct || !ss.eof()) 74 | { 75 | throw std::invalid_argument("Wrong date format: " + date_string); 76 | } 77 | 78 | date = { year, month, day }; 79 | 80 | return is; 81 | } 82 | -------------------------------------------------------------------------------- /White Belt/Week_5 (Final_project)/Updated/Date.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class Date 6 | { 7 | public: 8 | Date() = default; 9 | Date(const int year, const int month, const int day); 10 | 11 | int GetYear() const; 12 | int GetMonth() const; 13 | int GetDay() const; 14 | private: 15 | int year_ { 0 }, 16 | month_{ 0 }, 17 | day_ { 0 }; 18 | }; 19 | 20 | int ReadInt(std::stringstream& ss, bool& flag); 21 | void CheckSymbol(std::stringstream& ss, bool& flag); 22 | bool operator<(const Date& lhs, const Date& rhs); 23 | std::istream& operator>>(std::istream& is, Date& date); -------------------------------------------------------------------------------- /Yellow Belt/Week_1/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Даны значения температуры, наблюдавшиеся в течение N подряд идущих дней. 3 | Найдите номера дней (в нумерации с нуля) со значением температуры выше среднего арифметического за все N дней. 4 | 5 | Гарантируется, что среднее арифметическое значений температуры является целым числом. 6 | 7 | Формат ввода 8 | Вводится число N, затем N целых чисел — значения температуры в 0-й, 1-й, ... (N−1)-й день. 9 | Гарантируется, что N не превышает миллиона (10^6), а значения температуры, 10 | измеряющиеся в миллионных долях градусов по Цельсию, лежат в диапазоне от −10^8 до 10^8. 11 | Проверять соблюдение этих ограничений не нужно: вы можете ориентироваться на них при выборе наиболее подходящих типов для переменных. 12 | 13 | Формат вывода 14 | Первое число K — количество дней, значение температуры в которых выше среднего арифметического. 15 | Затем K целых чисел — номера этих дней. 16 | */ 17 | #include 18 | #include 19 | 20 | int main() 21 | { 22 | size_t day_count{ 0 }; 23 | int64_t sum{ 0 }; 24 | size_t day{ 0 }; 25 | 26 | std::vector temperatures; 27 | 28 | std::cin >> day_count; 29 | 30 | for (size_t i = 0; i < day_count; i++) 31 | { 32 | int64_t temperature{ 0 }; 33 | std::cin >> temperature; 34 | 35 | temperatures.push_back(temperature); 36 | sum += temperature; 37 | } 38 | 39 | int average = sum / static_cast(day_count); 40 | 41 | for (const int temperature : temperatures) 42 | { 43 | if (temperature > average) 44 | day++; 45 | } 46 | 47 | std::cout << day << std::endl; 48 | 49 | bool first{ true }; 50 | for (size_t i = 0; i < temperatures.size(); ++i) 51 | { 52 | if (temperatures.at(i) > average) 53 | { 54 | if (first) 55 | { 56 | std::cout << i; 57 | first = false; 58 | } 59 | else 60 | { 61 | std::cout << ' ' << i; 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_1/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Вычислите суммарную массу имеющих форму прямоугольного параллелепипеда бетонных блоков одинаковой плотности, но разного размера. 3 | 4 | Указание 5 | Считайте, что размеры блоков измеряются в сантиметрах, плотность — в граммах на кубический сантиметр, 6 | а итоговая масса — в граммах. Таким образом, массу блока можно вычислять как простое произведение плотности на объём. 7 | 8 | Формат ввода 9 | В первой строке вводятся два целых положительных числа: количество блоков N и плотность каждого блока R. 10 | Каждая из следующих N строк содержит три целых положительных числа W, H, D — размеры очередного блока. 11 | 12 | Гарантируется, что: 13 | 14 | количество блоков N не превосходит 10^5; 15 | плотность блоков R не превосходит 100; 16 | размеры блоков W, H, D не превосходят 10^4. 17 | */ 18 | #include 19 | #include 20 | #include 21 | 22 | class Block 23 | { 24 | public: 25 | Block(const uint64_t new_width, const uint64_t new_height, const uint64_t new_length) 26 | { 27 | _width = new_width; 28 | _height = new_height; 29 | _length = new_length; 30 | } 31 | 32 | uint64_t Squad() 33 | { 34 | return _width * _height* _length; 35 | } 36 | private: 37 | uint64_t _width; 38 | uint64_t _height; 39 | uint64_t _length; 40 | }; 41 | 42 | int main() 43 | { 44 | uint64_t count{}; 45 | uint64_t density{}; 46 | std::cin >> count >> density; 47 | 48 | std::vector blocks; 49 | 50 | for (size_t i = 0; i < count; i++) 51 | { 52 | uint64_t new_width{}, new_height{}, new_length{}; 53 | std::cin >> new_width >> new_height >> new_length; 54 | 55 | blocks.push_back({ new_width, new_height, new_length }); 56 | } 57 | 58 | uint64_t mass{ 0 }; 59 | 60 | for (Block& bl : blocks) 61 | { 62 | mass += bl.Squad() * density; 63 | } 64 | 65 | std::cout << mass << std::endl; 66 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_1/Task_7/Task_7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Реализуйте шаблонную функцию GetRefStrict, которая на вход принимает: map и значение ключа k.\ 3 | Если элемент по ключу k в коллекции отсутствует, то функция должна бросить исключение runtime_error, иначе вернуть ссылку на элемент в коллекции. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | template Value& GetRefStrict(std::map& map, const Key key); 12 | 13 | template 14 | Value& GetRefStrict(std::map& map, Key key) 15 | { 16 | if (map.count(key) == 0) 17 | throw std::runtime_error("Error"); 18 | 19 | return map.at(key); 20 | } 21 | 22 | int main() 23 | { 24 | std::map m = { {0, "value"} }; 25 | std::string& item = GetRefStrict(m, 0); 26 | item = "newvalue"; 27 | std::cout << m[0] << std::endl; // выведет newvalue 28 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Вам дан заголовочный файл sum_reverse_sort.h, содержащий объявления трёх функций 3 | #pragma once 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | int Sum(int x, int y); 10 | string Reverse(string s); 11 | void Sort(vector& nums); 12 | 13 | Вам надо прислать cpp-файл, содержащий определения этих функций. 14 | */ 15 | #include 16 | #include "sum_reverse_sort.h" 17 | 18 | int main() 19 | { 20 | std::cout << Sum(5, 7) << std::endl; 21 | 22 | std::cout << Reverse("qwerty") << std::endl; 23 | 24 | std::vector vec = { 5,3,2,4,1 }; 25 | Sort(vec); 26 | 27 | for (const auto num : vec) 28 | { 29 | std::cout << num << " "; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_1/Test_runner.cpp: -------------------------------------------------------------------------------- 1 | #include "Test_runner.h" 2 | 3 | void Assert(bool b, const std::string& hint) 4 | { 5 | AssertEqual(b, true, hint); 6 | } 7 | 8 | TestRunner::~TestRunner() 9 | { 10 | if (fail_count > 0) 11 | { 12 | std::cerr << fail_count << " unit tests failed. Terminate" << std::endl; 13 | exit(1); 14 | } 15 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_1/Test_runner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | std::ostream& operator << (std::ostream& os, const std::vector& s) 12 | { 13 | os << "{"; 14 | bool first = true; 15 | for (const auto& x : s) 16 | { 17 | if (!first) 18 | { 19 | os << ", "; 20 | } 21 | first = false; 22 | os << x; 23 | } 24 | return os << "}"; 25 | } 26 | 27 | template 28 | std::ostream& operator << (std::ostream& os, const std::set& s) 29 | { 30 | os << "{"; 31 | bool first = true; 32 | for (const auto& x : s) 33 | { 34 | if (!first) 35 | { 36 | os << ", "; 37 | } 38 | first = false; 39 | os << x; 40 | } 41 | return os << "}"; 42 | } 43 | 44 | template 45 | std::ostream& operator << (std::ostream& os, const std::map& m) 46 | { 47 | os << "{"; 48 | bool first = true; 49 | for (const auto& kv : m) 50 | { 51 | if (!first) 52 | { 53 | os << ", "; 54 | } 55 | first = false; 56 | os << kv.first << ": " << kv.second; 57 | } 58 | return os << "}"; 59 | } 60 | 61 | template 62 | void AssertEqual(const T& t, const U& u, const std::string& hint = {}) 63 | { 64 | if (t != u) 65 | { 66 | std::ostringstream os; 67 | os << "Assertion failed: " << t << " != " << u; 68 | if (!hint.empty()) 69 | { 70 | os << " hint: " << hint; 71 | } 72 | throw std::runtime_error(os.str()); 73 | } 74 | } 75 | 76 | void Assert(bool b, const std::string& hint); 77 | 78 | class TestRunner 79 | { 80 | public: 81 | template 82 | void RunTest(TestFunc func, const std::string& test_name) 83 | { 84 | try 85 | { 86 | func(); 87 | std::cerr << test_name << " OK" << std::endl; 88 | } 89 | catch (std::exception& e) 90 | { 91 | ++fail_count; 92 | std::cerr << test_name << " fail: " << e.what() << std::endl; 93 | } 94 | catch (...) 95 | { 96 | ++fail_count; 97 | std::cerr << "Unknown exception caught" << std::endl; 98 | } 99 | } 100 | 101 | ~TestRunner(); 102 | 103 | private: 104 | int fail_count = 0; 105 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_1/sum_reverse_sort.cpp: -------------------------------------------------------------------------------- 1 | #include "sum_reverse_sort.h" 2 | #include 3 | 4 | int Sum(int x, int y) 5 | { 6 | return x + y; 7 | } 8 | 9 | std::string Reverse(std::string s) 10 | { 11 | std::reverse(std::begin(s), std::end(s)); 12 | 13 | return s; 14 | } 15 | 16 | void Sort(std::vector& nums) 17 | { 18 | std::sort(nums.begin(), nums.end()); 19 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_1/sum_reverse_sort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | int Sum(int x, int y); 6 | std::string Reverse(std::string s); 7 | void Sort(std::vector& nums); -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Вам дан заголовочный файл phone_number.h, содержащий объявление класса PhoneNumber. 3 | При этом в комментариях описано поведение, которое ожидается от реализации этого класса. 4 | 5 | 6 | */ 7 | 8 | #include 9 | #include "phone_number.h" 10 | #include "UnitFramework.h" 11 | #include "UnitTests.h" 12 | 13 | int main() 14 | { 15 | UnitFramework uf; 16 | uf.RunTest(TestCorrectNumber, "Correct number"); 17 | uf.RunTest(TestCountyCode, "Contry Code"); 18 | uf.RunTest(TestCityCode, "City Code"); 19 | uf.RunTest(TestLocalNumber, "Local Numbers"); 20 | 21 | 22 | //PhoneNumber pn("+7-495-2387858"); 23 | //std::cout << pn.GetInternationalNumber() << ": " << pn.GetCountryCode() << " " << pn.GetCityCode() << " " << pn.GetLocalNumber() << std::endl; 24 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_2/UnitFramework.cpp: -------------------------------------------------------------------------------- 1 | #include "UnitFramework.h" 2 | 3 | void Assert(bool b, const std::string& hint) 4 | { 5 | AssertEqual(b, true, hint); 6 | } 7 | 8 | UnitFramework::~UnitFramework() 9 | { 10 | if (fail_count > 0) 11 | { 12 | std::cerr << fail_count << " unit tests failed. Terminate" << std::endl; 13 | exit(1); 14 | } 15 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_2/UnitFramework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template 11 | std::ostream& operator << (std::ostream& os, const std::vector& s) 12 | { 13 | os << "{"; 14 | bool first = true; 15 | for (const auto& x : s) 16 | { 17 | if (!first) 18 | { 19 | os << ", "; 20 | } 21 | first = false; 22 | os << x; 23 | } 24 | return os << "}"; 25 | } 26 | 27 | template 28 | std::ostream& operator << (std::ostream& os, const std::set& s) 29 | { 30 | os << "{"; 31 | bool first = true; 32 | for (const auto& x : s) 33 | { 34 | if (!first) 35 | { 36 | os << ", "; 37 | } 38 | first = false; 39 | os << x; 40 | } 41 | return os << "}"; 42 | } 43 | 44 | template 45 | std::ostream& operator << (std::ostream& os, const std::map& m) 46 | { 47 | os << "{"; 48 | bool first = true; 49 | for (const auto& kv : m) 50 | { 51 | if (!first) 52 | { 53 | os << ", "; 54 | } 55 | first = false; 56 | os << kv.first << ": " << kv.second; 57 | } 58 | return os << "}"; 59 | } 60 | 61 | template 62 | void AssertEqual(const T& t, const U& u, const std::string& hint = {}) 63 | { 64 | if (t != u) 65 | { 66 | std::ostringstream os; 67 | os << "Assertion failed: " << t << " != " << u; 68 | if (!hint.empty()) 69 | { 70 | os << " hint: " << hint; 71 | } 72 | throw std::runtime_error(os.str()); 73 | } 74 | } 75 | 76 | void Assert(bool b, const std::string& hint); 77 | 78 | class UnitFramework 79 | { 80 | public: 81 | template 82 | void RunTest(TestFunc func, const std::string& test_name) 83 | { 84 | try 85 | { 86 | func(); 87 | std::cerr << test_name << " OK" << std::endl; 88 | } 89 | catch (std::exception& e) 90 | { 91 | ++fail_count; 92 | std::cerr << test_name << " fail: " << e.what() << std::endl; 93 | } 94 | catch (...) 95 | { 96 | ++fail_count; 97 | std::cerr << "Unknown exception caught" << std::endl; 98 | } 99 | } 100 | 101 | ~UnitFramework(); 102 | 103 | private: 104 | int fail_count = 0; 105 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_2/UnitTests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void TestCorrectNumber(); 4 | 5 | void TestCountyCode(); 6 | 7 | void TestCityCode(); 8 | 9 | void TestLocalNumber(); -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_2/phone_number.cpp: -------------------------------------------------------------------------------- 1 | #include "phone_number.h" 2 | #include 3 | #include 4 | #include 5 | 6 | PhoneNumber::PhoneNumber(const std::string& international_number) 7 | { 8 | std::stringstream ss(international_number); 9 | 10 | char sigh = ss.get(); 11 | 12 | getline(ss, country_code_, '-'); 13 | 14 | getline(ss, city_code_, '-'); 15 | 16 | getline(ss, local_number_); 17 | 18 | if (sigh != '+' || country_code_.empty() || city_code_.empty() || local_number_.empty()) 19 | { 20 | throw std::invalid_argument("Wrong phone number: " + international_number); 21 | } 22 | } 23 | 24 | std::string PhoneNumber::GetCountryCode() const 25 | { 26 | return country_code_; 27 | } 28 | 29 | std::string PhoneNumber::GetCityCode() const 30 | { 31 | return city_code_; 32 | } 33 | std::string PhoneNumber::GetLocalNumber() const 34 | { 35 | return local_number_; 36 | } 37 | std::string PhoneNumber::GetInternationalNumber() const 38 | { 39 | return "+" + GetCountryCode() + "-" + GetCityCode() + "-" + GetLocalNumber(); 40 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_2/phone_number.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class PhoneNumber 6 | { 7 | public: 8 | /* Принимает строку в формате +XXX-YYY-ZZZZZZ 9 | Часть от '+' до первого '-' - это код страны. 10 | Часть между первым и вторым символами '-' - код города 11 | Всё, что идёт после второго символа '-' - местный номер. 12 | Код страны, код города и местный номер не должны быть пустыми. 13 | Если строка не соответствует этому формату, нужно выбросить исключение invalid_argument. Проверять, что номер содержит только цифры, не нужно. 14 | 15 | Примеры: 16 | * +7-495-111-22-33 17 | * +7-495-1112233 18 | * +323-22-460002 19 | * +1-2-coursera-cpp 20 | * 1-2-333 - некорректный номер - не начинается на '+' 21 | * +7-1233 - некорректный номер - есть только код страны и города 22 | */ 23 | explicit PhoneNumber(const std::string& international_number); 24 | 25 | std::string GetCountryCode() const; 26 | std::string GetCityCode() const; 27 | std::string GetLocalNumber() const; 28 | std::string GetInternationalNumber() const; 29 | 30 | private: 31 | std::string country_code_; 32 | std::string city_code_; 33 | std::string local_number_; 34 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_3/Rectangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Rectangle.h" 2 | 3 | Rectangle::Rectangle(int width, int height) : width_(width), height_(height) 4 | { 5 | 6 | } 7 | 8 | int Rectangle::GetArea() const 9 | { 10 | return width_ * height_; 11 | } 12 | 13 | int Rectangle::GetPerimeter() const 14 | { 15 | return 2 * (width_ + height_); 16 | } 17 | 18 | int Rectangle::GetWidth() const 19 | { 20 | return width_; 21 | } 22 | 23 | int Rectangle::GetHeight() const 24 | { 25 | return height_; 26 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_3/Rectangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Rectangle 4 | { 5 | public: 6 | Rectangle(int width, int height); 7 | 8 | int GetArea() const; 9 | int GetPerimeter() const; 10 | int GetWidth() const; 11 | int GetHeight() const; 12 | 13 | private: 14 | int width_, height_; 15 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Вам дано полное определение класса Rectangle: 3 | class Rectangle { 4 | public: 5 | Rectangle(int width, int height) : width_(width), height_(height) 6 | { 7 | } 8 | 9 | int GetArea() const { 10 | return width_ * height_; 11 | } 12 | 13 | int GetPerimeter() const { 14 | return 2 * (width_ + height_); 15 | } 16 | 17 | int GetWidth() const { return width_; } 18 | int GetHeight() const { return height_; } 19 | 20 | private: 21 | int width_, height_; 22 | }; 23 | 24 | Пришлите заголовочный файл rectangle.h, содержащий объявление класса Rectangle. 25 | Это должен быть полноценный заголовочный файл, который можно использовать в большом проекте. 26 | В частности, в нём должна быть решена проблема двойного включения. 27 | */ 28 | 29 | #include 30 | #include "Rectangle.h" 31 | 32 | int main() 33 | { 34 | Rectangle r(5,10); 35 | std::cout << "Area: " << r.GetArea() << std::endl; 36 | std::cout << "Perimeter: " << r.GetPerimeter() << std::endl; 37 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_4/Task_4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В задаче «Декомпозиция программы» мы разбили монолитный код на набор функций и классов. 3 | Теперь мы сделаем ещё один шаг и разделим нашу программу на несколько файлов. 4 | В этой задаче вам нужно создать проект, состоящий из следующих файлов: 5 | 1.query.h, в него кладём: 6 | enum class QueryType 7 | struct Query 8 | объявление istream& operator >> (istream& is, Query& q) 9 | 2. query.cpp, в него кладём 10 | определение istream& operator >> (istream& is, Query& q); 11 | 3. responses.h: 12 | struct BusesForStopResponse 13 | ostream& operator << (ostream& os, const BusesForStopResponse& r) 14 | struct StopsForBusResponse 15 | ostream& operator << (ostream& os, const StopsForBusResponse& r) 16 | struct AllBusesResponse 17 | ostream& operator << (ostream& os, const AllBusesResponse& r) 18 | 4. responses.cpp: определения всего, что объявлено в responses.h 19 | 5. bus_manager.h: объявление класса BusManager 20 | 6. bus_manager.cpp: определения методов класса BusManager 21 | 7. main.cpp: функция main 22 | */ 23 | 24 | #include 25 | #include "query.h" 26 | #include "bus_manager.h" 27 | 28 | int main() 29 | { 30 | int query_count; 31 | Query q; 32 | 33 | std::cin >> query_count; 34 | 35 | BusManager bm; 36 | for (int i = 0; i < query_count; ++i) { 37 | std::cin >> q; 38 | switch (q.type) 39 | { 40 | case QueryType::NewBus: 41 | bm.AddBus(q.bus, q.stops); 42 | break; 43 | case QueryType::BusesForStop: 44 | std::cout << bm.GetBusesForStop(q.stop) << std::endl; 45 | break; 46 | case QueryType::StopsForBus: 47 | std::cout << bm.GetStopsForBus(q.bus) << std::endl; 48 | break; 49 | case QueryType::AllBuses: 50 | std::cout << bm.GetAllBuses() << std::endl; 51 | break; 52 | } 53 | } 54 | 55 | return 0; 56 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_4/bus_manager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Yellow Belt/Week_3/Task_4/bus_manager.cpp -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_4/bus_manager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Yellow Belt/Week_3/Task_4/bus_manager.h -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_4/query.cpp: -------------------------------------------------------------------------------- 1 | #include "query.h" 2 | #include 3 | 4 | std::istream& operator >> (std::istream& is, Query& q) 5 | { 6 | std::string cmd; 7 | is >> cmd; 8 | 9 | std::map commands = 10 | { 11 | {"NEW_BUS", QueryType::NewBus}, 12 | {"BUSES_FOR_STOP",QueryType::BusesForStop}, 13 | {"STOPS_FOR_BUS", QueryType::StopsForBus}, 14 | {"ALL_BUSES", QueryType::AllBuses} 15 | }; 16 | 17 | q.type = commands.at(cmd); 18 | 19 | switch (q.type) 20 | { 21 | case QueryType::NewBus: 22 | is >> q.bus; 23 | is.ignore(1); 24 | size_t stop_count; 25 | is >> stop_count; 26 | q.stops.clear(); 27 | for (size_t i = 0; i < stop_count; i++) 28 | { 29 | std::string stop; 30 | is >> stop; 31 | q.stops.push_back(stop); 32 | } 33 | break; 34 | case QueryType::BusesForStop: 35 | is >> q.stop; 36 | break; 37 | case QueryType::StopsForBus: 38 | is >> q.bus; 39 | break; 40 | case QueryType::AllBuses: 41 | ; 42 | break; 43 | } 44 | 45 | return is; 46 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_4/query.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | enum class QueryType 8 | { 9 | NewBus, 10 | BusesForStop, 11 | StopsForBus, 12 | AllBuses 13 | }; 14 | 15 | struct Query 16 | { 17 | QueryType type; 18 | std::string bus; 19 | std::string stop; 20 | std::vector stops; 21 | }; 22 | 23 | std::istream& operator>> (std::istream& is, Query& q); -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_4/responses.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Yellow Belt/Week_3/Task_4/responses.cpp -------------------------------------------------------------------------------- /Yellow Belt/Week_3/Task_4/responses.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Yellow Belt/Week_3/Task_4/responses.h -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Напишите функцию PrintVectorPart, принимающую вектор целых чисел numbers, 3 | выполняющую поиск первого отрицательного числа в нём и выводящую в стандартный вывод все числа, 4 | расположенные левее найденного, в обратном порядке. 5 | Если вектор не содержит отрицательных чисел, выведите все числа в обратном порядке. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | void PrintVectorPart(const std::vector& numbers) 13 | { 14 | auto it = std::find_if(numbers.begin(), numbers.end(), [](int x) 15 | { 16 | return x < 0; 17 | }); 18 | 19 | while (it != numbers.begin()) 20 | { 21 | --it; 22 | std::cout << *it << ' '; 23 | } 24 | } 25 | 26 | int main() 27 | { 28 | PrintVectorPart({ 6, 1, 8, -5, 4 }); 29 | std::cout << std::endl; 30 | PrintVectorPart({ -6, 1, 8, -5, 4 }); // ничего не выведется 31 | std::cout << std::endl; 32 | PrintVectorPart({ 6, 1, 8, 5, 4 }); 33 | std::cout << std::endl; 34 | return 0; 35 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_10/FindStartsWithChar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | template 8 | std::pair FindStartsWithChar(RandomIt range_begin, RandomIt range_end, char prefix); 9 | 10 | template 11 | std::pair FindStartsWithChar(RandomIt range_begin, RandomIt range_end, char prefix) 12 | { 13 | auto lower = std::lower_bound(range_begin, range_end, std::string(1, prefix)); 14 | 15 | auto upper = std::upper_bound(range_begin, range_end, std::string(1, prefix), 16 | [](const std::string& lhs, const std::string& rhs) 17 | { 18 | std::string buffer = rhs; 19 | buffer.resize(lhs.size()); 20 | 21 | if (lhs != buffer && lhs < rhs) 22 | { 23 | return true; 24 | } 25 | 26 | return false; 27 | }); 28 | 29 | return { lower, upper }; 30 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_10/FindStartsWithPrefix.cpp: -------------------------------------------------------------------------------- 1 | #include "FindStartsWithPrefix.h" 2 | 3 | bool Comp(const std::string& lhs, const std::string& rhs) 4 | { 5 | std::string buffer = rhs; 6 | buffer.resize(lhs.size()); 7 | 8 | if (lhs != buffer && lhs < rhs) 9 | return true; 10 | 11 | return false; 12 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_10/FindStartsWithPrefix.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | template 8 | std::pair FindStartsWithPrefix(RandomIt range_begin, RandomIt range_end, const std::string& prefix); 9 | 10 | bool Comp(const std::string& lhs, const std::string& rhs); 11 | 12 | template 13 | std::pair FindStartsWithPrefix(RandomIt range_begin, RandomIt range_end, const std::string& prefix) 14 | { 15 | auto lower = std::lower_bound(range_begin, range_end, prefix); 16 | 17 | auto upper = std::upper_bound(range_begin, range_end, prefix, Comp); 18 | 19 | return { lower, upper }; 20 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_2/FindGreaterElements.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | template 8 | std::vector FindGreaterElements(const std::set& elements, const T& border); 9 | 10 | template 11 | std::vector FindGreaterElements(const std::set& elements, const T& border) 12 | { 13 | auto it = std::find_if(elements.begin(), elements.end(), [border] (T n) 14 | { 15 | return n > border; 16 | }); 17 | 18 | return { it, elements.end() }; 19 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Напишите шаблонную функцию FindGreaterElements, 3 | принимающую множество elements объектов типа T и ещё один объект border типа T и возвращающую вектор из всех элементов множества, 4 | бо́льших border, в возрастающем порядке. 5 | */ 6 | 7 | #include 8 | #include "FindGreaterElements.h" 9 | 10 | int main() { 11 | for (int x : FindGreaterElements(std::set{1, 5, 7, 8}, 5)) { 12 | std::cout << x << " "; 13 | } 14 | std::cout << std::endl; 15 | 16 | for (int x : FindGreaterElements(std::set{1, 5, 7, 8}, 0)) { 17 | std::cout << x << " "; 18 | } 19 | std::cout << std::endl; 20 | 21 | std::string to_find = "Python"; 22 | std::cout << FindGreaterElements(std::set{"C", "C++"}, to_find).size() << std::endl; 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Напишите функцию SplitIntoWords, разбивающую строку на слова по пробелам. 3 | Гарантируется, что: 4 | 1) строка непуста; 5 | 2) строка состоит лишь из латинских букв и пробелов; 6 | 3) первый и последний символы строки не являются пробелами; 7 | 4) строка не содержит двух пробелов подряд. 8 | Подсказка 9 | Рекомендуется следующий способ решения задачи: 10 | 1) искать очередной пробел с помощью алгоритма find; 11 | 2) создавать очередное слово с помощью конструктора строки по двум итераторам. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | std::vector SplitIntoWords(const std::string& s); 19 | 20 | int main() 21 | { 22 | std::string s = "C Cpp Java Python"; //4 С/Cpp/Java/Python 23 | 24 | std::vector words = SplitIntoWords(s); 25 | std::cout << words.size() << " "; 26 | for (auto it = std::begin(words); it != std::end(words); ++it) 27 | { 28 | if (it != std::begin(words)) { 29 | std::cout << "/"; 30 | } 31 | std::cout << *it; 32 | } 33 | std::cout << std::endl; 34 | 35 | return 0; 36 | } 37 | 38 | std::vector SplitIntoWords(const std::string& s) 39 | { 40 | std::vector result; 41 | 42 | auto it_begin = s.begin(); 43 | auto it_end = s.begin(); 44 | 45 | for (auto it = s.begin(); it != s.end(); ++it) 46 | { 47 | if (*it == ' ') 48 | { 49 | it_end = it; 50 | result.push_back({ it_begin, it_end }); 51 | if (it != s.end()) 52 | { 53 | it_begin = ++it; 54 | } 55 | } 56 | } 57 | 58 | result.push_back({ it_begin , s.end() }); 59 | 60 | return result; 61 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_4/RemoveDuplicates.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | template 7 | void RemoveDuplicates(std::vector& elements) 8 | { 9 | std::sort(elements.begin(), elements.end()); 10 | auto it = std::unique(elements.begin(), elements.end()); 11 | elements.erase(it, elements.end()); 12 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_4/Task_4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Напишите шаблонную функцию RemoveDuplicates, 3 | принимающую по ссылке вектор elements объектов типа T и удаляющую из него все дубликаты элементов. 4 | Порядок оставшихся элементов может быть любым. 5 | 6 | Гарантируется, что объекты типа T можно сравнивать с помощью операторов ==, !=, < и >. 7 | */ 8 | 9 | #include 10 | #include "RemoveDuplicates.h" 11 | 12 | int main() { 13 | std::vector v1 = { 6, 4, 7, 6, 4, 4, 0, 1 }; 14 | RemoveDuplicates(v1); 15 | for (int x : v1) { 16 | std::cout << x << " "; 17 | } 18 | std::cout << std::endl; 19 | 20 | std::vector v2 = { "C", "C++", "C++", "C", "C++" }; 21 | RemoveDuplicates(v2); 22 | for (const std::string& s : v2) { 23 | std::cout << s << " "; 24 | } 25 | std::cout << std::endl; 26 | return 0; 27 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_5/Task_5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Дано целое положительное число N, не превышающее 9. 3 | Выведите все перестановки чисел от 1 до N в обратном лексикографическом порядке. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void PrintPermutations(const int size); 12 | std::ostream& operator<< (std::ostream& os, const std::vector& vec); 13 | 14 | int main() 15 | { 16 | int n; 17 | std::cin >> n; 18 | PrintPermutations(n); 19 | } 20 | 21 | void PrintPermutations(const int size) 22 | { 23 | std::vector result(size); 24 | 25 | std::iota(std::rbegin(result), std::rend(result), 1); 26 | 27 | do 28 | { 29 | std::cout << result << std::endl; 30 | } while (std::prev_permutation(std::begin(result), std::end(result))); 31 | } 32 | 33 | std::ostream& operator<< (std::ostream& os, const std::vector& vec) 34 | { 35 | bool first = true; 36 | for (const auto el : vec) 37 | { 38 | if (!first) 39 | { 40 | os << ' '; 41 | } 42 | first = false; 43 | os << el; 44 | } 45 | 46 | return os; 47 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_6/ComputeMedianAge.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | template 6 | int ComputeMedianAge(InputIt range_begin, InputIt range_end) 7 | { 8 | if (range_begin == range_end) 9 | { 10 | return 0; 11 | } 12 | 13 | std::vector range_copy(range_begin, range_end); 14 | 15 | auto middle = std::begin(range_copy) + range_copy.size() / 2; 16 | 17 | std::nth_element( 18 | std::begin(range_copy), middle, std::end(range_copy), 19 | [](const Person& lhs, const Person& rhs) 20 | { 21 | return lhs.age < rhs.age; 22 | } 23 | ); 24 | 25 | return middle->age; 26 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_6/Person.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Person.h" 4 | #include "ComputeMedianAge.h" 5 | 6 | void PrintStats(std::vector persons) 7 | { 8 | auto female_end = std::partition(std::begin(persons), std::end(persons), 9 | [](const Person& person) 10 | { 11 | return person.gender == Gender::FEMALE; 12 | }); 13 | 14 | auto female_empl = std::partition(std::begin(persons), female_end, 15 | [](const Person& person) 16 | { 17 | return person.is_employed == true; 18 | }); 19 | 20 | auto male_empl = std::partition(female_end, std::end(persons), 21 | [](const Person& person) 22 | { 23 | return person.is_employed == true; 24 | }); 25 | 26 | std::cout << "Median age = " << ComputeMedianAge(std::begin(persons), std::end(persons)) << std::endl; 27 | std::cout << "Median age for females = " << ComputeMedianAge(std::begin(persons), female_end) << std::endl; 28 | std::cout << "Median age for males = " << ComputeMedianAge(female_end, std::end(persons)) << std::endl; 29 | 30 | std::cout << "Median age for employed females = " << ComputeMedianAge(std::begin(persons), female_empl) << std::endl; 31 | std::cout << "Median age for unemployed females = " << ComputeMedianAge(female_empl, female_end) << std::endl; 32 | std::cout << "Median age for employed males = " << ComputeMedianAge(female_end, male_empl) << std::endl; 33 | std::cout << "Median age for unemployed males = " << ComputeMedianAge(male_empl, std::end(persons)) << std::endl; 34 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_6/Person.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/Yellow Belt/Week_4/Task_6/Person.h -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_6/Task_6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В этой задаче вам необходимо вычислить различные демографические показатели для группы людей. 3 | Человек представляется структурой Person: 4 | struct Person 5 | { 6 | int age; // возраст 7 | Gender gender; // пол 8 | bool is_employed; // имеет ли работу 9 | }; 10 | 11 | Тип Gender определён следующим образом: 12 | enum class Gender 13 | { 14 | FEMALE, 15 | MALE 16 | }; 17 | 18 | Вам необходимо написать функцию PrintStats, получающую вектор людей, 19 | вычисляющую и выводящую медианный возраст для каждой из следующих групп людей: 20 | 21 | 1) все люди; 22 | 2) все женщины; 23 | 3) все мужчины; 24 | 4) все безработные женщины; 25 | 5) все занятые женщины; 26 | 6) все безработные мужчины; 27 | 7) все занятые мужчины. 28 | 29 | Все 7 чисел нужно вывести в строгом соответствии с форматом. 30 | 31 | void PrintStats(vector persons); 32 | Принимая вектор по значению (а не по константной ссылке), 33 | вы получаете возможность модифицировать его копию произвольным образом и тем самым проще произвести вычисления. 34 | 35 | Вычисление медианного возраста 36 | Для вычисления медианного возраста группы людей вы должны использовать функцию ComputeMedianAge: 37 | template 38 | int ComputeMedianAge(InputIt range_begin, InputIt range_end); 39 | 40 | Эту функцию не нужно реализовывать самостоятельно: 41 | мы реализовали её за вас и автоматически добавим к каждому вашему решению. 42 | 43 | Функцию ComputeMedianAge можно вызвать и для пустого набора людей: 44 | её результат в этом случае и нужно считать медианным возрастом пустого набора людей. 45 | */ 46 | 47 | #include 48 | #include 49 | #include "Person.h" 50 | 51 | int main() 52 | { 53 | std::vector persons = { 54 | {31, Gender::MALE, false}, 55 | {40, Gender::FEMALE, true}, 56 | {24, Gender::MALE, true}, 57 | {20, Gender::FEMALE, true}, 58 | {80, Gender::FEMALE, false}, 59 | {78, Gender::MALE, false}, 60 | {10, Gender::FEMALE, false}, 61 | {55, Gender::MALE, true}, 62 | }; 63 | 64 | PrintStats(persons); 65 | return 0; 66 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_7/MergeSort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | template 7 | void MergeSort(RandomIt range_begin, RandomIt range_end) 8 | { 9 | if (range_end - range_begin < 2) 10 | return; 11 | 12 | std::vector elements{ range_begin, range_end }; 13 | 14 | auto range_middle = std::begin(elements) + (std::end(elements) - std::begin(elements)) / 2; 15 | 16 | MergeSort(std::begin(elements), range_middle); 17 | MergeSort(range_middle, std::end(elements)); 18 | 19 | std::merge( 20 | std::begin(elements), range_middle, 21 | range_middle, std::end(elements), 22 | range_begin 23 | ); 24 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_7/MergeSort_Div3.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | template 7 | void MergeSort_Div3(RandomIt range_begin, RandomIt range_end) 8 | { 9 | if (range_end - range_begin < 2) 10 | return; 11 | 12 | std::vector elements{ range_begin, range_end }; 13 | 14 | auto range_first_middle = std::begin(elements) + (std::end(elements) - std::begin(elements)) / 3; 15 | 16 | auto range_second_middle = std::begin(elements) + ((std::end(elements) - std::begin(elements)) / 3 * 2); 17 | 18 | MergeSort_Div3(std::begin(elements), range_first_middle); 19 | MergeSort_Div3(range_first_middle, range_second_middle); 20 | MergeSort_Div3(range_second_middle, std::end(elements)); 21 | 22 | std::vector buffer; 23 | 24 | std::merge( 25 | std::begin(elements), range_first_middle, 26 | range_first_middle, range_second_middle, 27 | std::back_inserter(buffer) 28 | ); 29 | 30 | std::merge( 31 | std::begin(buffer), std::end(buffer), 32 | range_second_middle, std::end(elements), 33 | range_begin 34 | ); 35 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_7/Task_7.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Напишите шаблонную функцию MergeSort, принимающую два итератора шаблонного типа RandomIt и сортирующую заданный ими диапазон с помощью сортировки слиянием. 3 | Гарантируется, что: 4 | 1) итераторы типа RandomIt аналогичны по функциональности итераторам вектора и строки, 5 | то есть их можно сравнивать с помощью операторов <, <=, > и >=, а также вычитать и складывать с числами; 6 | 2) сортируемые объекты можно сравнивать с помощью оператора <. 7 | 8 | template 9 | void MergeSort(RandomIt range_begin, RandomIt range_end); 10 | 11 | Часть 1. Реализация с разбиением на 2 части 12 | Алгоритм 13 | Классический алгоритм сортировки слиянием выглядит следующим образом: 14 | 15 | 1) Если диапазон содержит меньше 2 элементов, выйти из функции. 16 | 2) Создать вектор, содержащий все элементы текущего диапазона. 17 | 3) Разбить вектор на две равные части. (В этой задаче гарантируется, что длина передаваемого диапазона является степенью двойки, так что вектор всегда можно разбить на две равные части.) 18 | 4) Вызвать функцию MergeSort от каждой половины вектора. 19 | 5) С помощью алгоритма merge слить отсортированные половины, записав полученный отсортированный диапазон вместо исходного. 20 | 21 | Вы должны реализовать именно этот алгоритм и никакой другой: тестирующая система будет проверять, что вы выполняете с элементами именно эти действия. 22 | 23 | 24 | Часть 2. Реализация с разбиением на 3 части 25 | Реализуйте сортировку слиянием, разбивая диапазон на 3 равные части, а не на 2. 26 | Гарантируется, что длина исходного диапазона является степенью 3. 27 | 28 | Соответственно, пункты 3–5 алгоритма нужно заменить следующими: 29 | 1) Разбить вектор на 3 равные части. 30 | 2) Вызвать функцию MergeSort от каждой части вектора. 31 | 3) Слить первые две трети вектора с помощью алгоритма merge, сохранив результат во временный вектор с помощью back_inserter. 32 | 4) Слить временный вектор из предыдущего пункта с последней третью вектора из п. 2, записав полученный отсортированный диапазон вместо исходного. 33 | */ 34 | #include 35 | #include "MergeSort.h" 36 | #include "MergeSort_Div3.h" 37 | 38 | 39 | #include 40 | 41 | int main() 42 | { 43 | std::vector v = { 6, 4, 7, 6, 10, 4, 0, 1 }; 44 | 45 | MergeSort(std::begin(v), std::end(v)); 46 | for (const int x : v) 47 | { 48 | std::cout << x << " "; 49 | } 50 | std::cout << std::endl; 51 | 52 | std::vector vec = { 6, 4, 7, 6, 4, 4, 0, 1, 5 }; 53 | MergeSort_Div3(begin(vec), end(vec)); 54 | for (int x : vec) { 55 | std::cout << x << " "; 56 | } 57 | std::cout << std::endl; 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_8/Task_8.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Напишите функцию FindNearestElement, 3 | для множества целых чисел numbers и данного числа border возвращающую итератор на элемент множества, 4 | ближайший к border. 5 | Если ближайших элементов несколько, верните итератор на наименьший из них. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | std::set::const_iterator FindNearestElement(const std::set& numbers, int border); 13 | 14 | int main() 15 | { 16 | std::set numbers = { 1, 4, 6 }; 17 | std::cout << 18 | *FindNearestElement(numbers, 0) << " " << 19 | *FindNearestElement(numbers, 3) << " " << 20 | *FindNearestElement(numbers, 5) << " " << 21 | *FindNearestElement(numbers, 6) << " " << 22 | *FindNearestElement(numbers, 100) << std::endl; 23 | 24 | std::set empty_set; 25 | 26 | std::cout << (FindNearestElement(empty_set, 8) == end(empty_set)) << std::endl; 27 | 28 | return 0; 29 | } 30 | 31 | std::set::const_iterator FindNearestElement(const std::set& numbers, int border) 32 | { 33 | 34 | const auto first_not_less = numbers.lower_bound(border); 35 | //если border меньше Min, то возвращаем begin() 36 | if (first_not_less == numbers.begin()) 37 | { 38 | return first_not_less; 39 | } 40 | 41 | const auto last_less = prev(first_not_less); 42 | //если border больше Max и указывает на end(), то возвращаем предыдущее 43 | if (first_not_less == numbers.end()) 44 | { 45 | return last_less; 46 | } 47 | 48 | //сравнение к какому значению ближе border к last_less или first_not_less 49 | const bool is_left = (border - *first_not_less <= *last_less - border); 50 | return is_left ? last_less : first_not_less; 51 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_9/Person.cpp: -------------------------------------------------------------------------------- 1 | #include "Person.h" 2 | 3 | void Person::ChangeFirstName(int year, const std::string& first_name) 4 | { 5 | first_name_history_[year] = first_name; 6 | } 7 | 8 | void Person::ChangeLastName(int year, const std::string& last_name) 9 | { 10 | last_name_history_[year] = last_name; 11 | } 12 | 13 | std::string Person::FindNameByYear(const std::map& name_history, const int year) 14 | { 15 | auto name_year = name_history.upper_bound(year); 16 | 17 | std::string name; 18 | if (name_year != name_history.begin()) 19 | { 20 | name = std::prev(name_year)->second; 21 | } 22 | 23 | return name; 24 | } 25 | 26 | std::string Person::GetFullName(int year) 27 | { 28 | const std::string first_name = FindNameByYear(first_name_history_, year); 29 | const std::string last_name = FindNameByYear(last_name_history_, year); 30 | 31 | if (first_name.empty() && last_name.empty()) 32 | { 33 | return "Incognito"; 34 | } 35 | 36 | if (!first_name.empty() && last_name.empty()) 37 | { 38 | return first_name + " with unknown last name"; 39 | } 40 | 41 | if (first_name.empty() && !last_name.empty()) 42 | { 43 | return last_name + " with unknown first name"; 44 | } 45 | 46 | return first_name + " " + last_name; 47 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_9/Person.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class Person 7 | { 8 | public: 9 | void ChangeFirstName(int year, const std::string& first_name); 10 | void ChangeLastName(int year, const std::string& last_name); 11 | std::string GetFullName(int year); 12 | private: 13 | std::map first_name_history_; 14 | std::map last_name_history_; 15 | std::string FindNameByYear(const std::map& name_history, const int year); 16 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_4/Task_9/Task_9.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Решите задачу «Имена и фамилии — 1» более эффективно, использовав двоичный поиск в методе Person::GetFullName. Напомним условие задачи. 3 | 4 | Реализуйте класс для человека, поддерживающий историю изменений человеком своих фамилии и имени. 5 | 6 | Считайте, что в каждый год может произойти не более одного изменения фамилии и не более одного изменения имени. 7 | При этом с течением времени могут открываться всё новые факты из прошлого человека, 8 | поэтому года́ в последовательных вызовах методов ChangeLastName и ChangeFirstName не обязаны возрастать. 9 | 10 | Гарантируется, что все имена и фамилии непусты. 11 | 12 | Строка, возвращаемая методом GetFullName, должна содержать разделённые одним пробелом имя и фамилию человека по состоянию на конец данного года. 13 | 14 | 1) Если к данному году не случилось ни одного изменения фамилии и имени, верните строку "Incognito". 15 | 2) Если к данному году случилось изменение фамилии, но не было ни одного изменения имени, верните "last_name with unknown first name". 16 | 3) Если к данному году случилось изменение имени, но не было ни одного изменения фамилии, верните "first_name with unknown last name". 17 | */ 18 | 19 | #include 20 | #include 21 | #include "Person.h" 22 | 23 | int main() { 24 | Person person; 25 | 26 | person.ChangeFirstName(1965, "Polina"); 27 | person.ChangeLastName(1967, "Sergeeva"); 28 | for (int year : {1900, 1965, 1990}) { 29 | std::cout << person.GetFullName(year) << std::endl; 30 | } 31 | 32 | person.ChangeFirstName(1970, "Appolinaria"); 33 | for (int year : {1969, 1970}) { 34 | std::cout << person.GetFullName(year) << std::endl; 35 | } 36 | 37 | person.ChangeLastName(1968, "Volkova"); 38 | for (int year : {1969, 1970}) { 39 | std::cout << person.GetFullName(year) << std::endl; 40 | } 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_1/Task_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Дан следующий код: 3 | 4 | #include 5 | 6 | using namespace std; 7 | 8 | class Animal { 9 | public: 10 | // ваш код 11 | 12 | const string Name; 13 | }; 14 | 15 | 16 | class Dog { 17 | public: 18 | // ваш код 19 | 20 | void Bark() { 21 | cout << Name << " barks: woof!" << endl; 22 | } 23 | }; 24 | 25 | Определите до конца тела классов, соблюдая следующие требования: 26 | 27 | 1) Класс Dog должен являться наследником класса Animal. 28 | 2) Конструктор класса Dog должен принимать параметр типа string и инициализировать им поле Name в классе Animal. 29 | 30 | */ 31 | 32 | #include 33 | 34 | class Animal 35 | { 36 | public: 37 | Animal(const std::string& name) : Name(name) 38 | { 39 | } 40 | 41 | const std::string Name; 42 | }; 43 | 44 | class Dog : public Animal 45 | { 46 | public: 47 | Dog(const std::string& name) : Animal(name) 48 | { 49 | } 50 | 51 | void Bark() 52 | { 53 | std::cout << Name << " barks: woof!" << std::endl; 54 | } 55 | }; 56 | 57 | int main() 58 | { 59 | Dog d("Charlie"); 60 | d.Bark(); 61 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_2/Task_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | В этой задаче вам нужно разработать классы SmsNotifier и EmailNotifier, 3 | отправляющие уведомления в виде SMS и e-mail соответственно, а также абстрактный базовый класс для них. 4 | 5 | Вам даны функции SendSms и SendEmail, которые моделируют отправку SMS и e-mail. 6 | void SendSms(const string& number, const string& message); 7 | void SendEmail(const string& email, const string& message); 8 | 9 | Разработайте: 10 | 1. Абстрактный базовый класс INotifier, у которого будет один чисто виртуальный метод void Notify(const string& message). 11 | 2. Класс SmsNotifier, который: 12 | 1) является потомком класса INotifier; 13 | 2) в конструкторе принимает один параметр типа string — номер телефона; 14 | 3) переопределяет метод Notify и вызывает из него функцию SendSms. 15 | 3. Класс EmailNotifier, который; 16 | 1) является потомком класса INotifier; 17 | 2) в конструкторе принимает один параметр типа string — адрес электронной почты; 18 | 3) переопределяет метод Notify и вызывает из него функцию SendEmail. 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | void SendSms(const std::string& number, const std::string& message) 25 | { 26 | std::cout << "Send '" << message << "' to number " << number << std::endl; 27 | } 28 | 29 | void SendEmail(const std::string& email, const std::string& message) 30 | { 31 | std::cout << "Send '" << message << "' to number " << email << std::endl; 32 | } 33 | 34 | class INotifier 35 | { 36 | public: 37 | virtual void Notify(const std::string& message) const = 0; 38 | }; 39 | 40 | class SmsNotifier : public INotifier 41 | { 42 | public: 43 | SmsNotifier(const std::string& phone_number) : phone_number_(phone_number){} 44 | void Notify(const std::string& message) const override 45 | { 46 | SendSms(phone_number_, message); 47 | } 48 | 49 | private: 50 | const std::string phone_number_; 51 | }; 52 | 53 | class EmailNotifier : public INotifier 54 | { 55 | public: 56 | EmailNotifier(const std::string& email_adress) : email_adress_(email_adress) {} 57 | void Notify(const std::string& message) const override 58 | { 59 | SendEmail(email_adress_, message); 60 | } 61 | private: 62 | std::string email_adress_; 63 | }; 64 | 65 | void Notify(INotifier& notifier, const std::string& message) 66 | { 67 | notifier.Notify(message); 68 | } 69 | 70 | int main() 71 | { 72 | SmsNotifier sms{ "+7-495-777-77-77" }; 73 | EmailNotifier email{ "na-derevnyu@dedushke.ru" }; 74 | 75 | Notify(sms, "I have White belt in C++"); 76 | Notify(email, "And want a Yellow one"); 77 | return 0; 78 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_3/Circle.cpp: -------------------------------------------------------------------------------- 1 | #include "Circle.h" 2 | 3 | std::string Circle::Name() const 4 | { 5 | return name_; 6 | } 7 | 8 | double Circle::Perimeter() const 9 | { 10 | const double pi = 3.14; 11 | return 2 * radius_ * pi; 12 | } 13 | 14 | double Circle::Area() const 15 | { 16 | const double pi = 3.14; 17 | return pi * radius_ * radius_; 18 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_3/Circle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Figure.h" 4 | 5 | class Circle : public Figure 6 | { 7 | public: 8 | Circle(const std::string& name, const double& radius) : name_(name), radius_(radius) {} 9 | 10 | std::string Name() const override; 11 | 12 | double Perimeter() const override; 13 | 14 | double Area() const override; 15 | private: 16 | const std::string name_; 17 | const double radius_; 18 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_3/Figure.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class Figure 6 | { 7 | public: 8 | virtual std::string Name() const = 0; 9 | virtual double Perimeter() const = 0; 10 | virtual double Area() const = 0; 11 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_3/Rect.cpp: -------------------------------------------------------------------------------- 1 | #include "Rect.h" 2 | 3 | std::string Rect::Name() const 4 | { 5 | return name_; 6 | } 7 | 8 | double Rect::Perimeter() const 9 | { 10 | return 2 * (height_ + width_); 11 | } 12 | 13 | double Rect::Area() const 14 | { 15 | return height_ * width_; 16 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_3/Rect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Figure.h" 4 | 5 | class Rect : public Figure 6 | { 7 | public: 8 | Rect(const std::string& name, const double& height, const double& width) : name_(name), height_(height), width_(width) {} 9 | 10 | std::string Name() const override; 11 | 12 | double Perimeter() const override; 13 | 14 | double Area() const override; 15 | 16 | private: 17 | const std::string name_; 18 | const double height_; 19 | const double width_; 20 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_3/Task_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Как видно из кода, есть два вида команд: 3 | 1) ADD — добавить фигуру в набор; 4 | 2) PRINT — для каждой фигуры в наборе распечатать название, периметр и площадь. 5 | Программа поддерживает три вида фигур: прямоугольник, треугольник и круг. 6 | Их добавление описывается так: 7 | 1) ADD RECT width height — добавить прямоугольник с размерами width и height (например, ADD RECT 2 3). 8 | 2) ADD TRIANGLE a b c — добавить треугольник со сторонами a, b и c (например, ADD TRIANGLE 3 4 5). 9 | 3) ADD CIRCLE r — добавить круг радиуса r (например, ADD CIRCLE 5). 10 | 11 | Не меняя функцию main, реализуйте недостающие функции и классы: 12 | 13 | 1) базовый класс Figure с чисто виртуальными методами Name, Perimeter и Area; 14 | 2) классы Triangle, Rect и Circle, которые являются наследниками класса Figure и переопределяют его виртуальные методы; 15 | 3) функцию CreateFigure, которая в зависимости от содержимого входного потока создаёт 16 | shared_ptr, shared_ptr или shared_ptr. 17 | 18 | Гарантируется, что все команды ADD корректны; 19 | размеры всех фигур — это натуральные числа не больше 1000. 20 | В качестве значения π используйте 3,14. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "Figure.h" 30 | #include "Rect.h" 31 | #include "Triangle.h" 32 | #include "Circle.h" 33 | 34 | std::shared_ptr
CreateFigure(std::istringstream& is) 35 | { 36 | std::string figure; 37 | is >> figure; 38 | if (figure == "RECT") 39 | { 40 | double height, width; 41 | is >> height >> width; 42 | 43 | return std::make_shared(figure, height, width); 44 | } 45 | else if (figure == "TRIANGLE") 46 | { 47 | double side_a, side_b, side_c; 48 | is >> side_a >> side_b >> side_c; 49 | 50 | return std::make_shared(figure, side_a, side_b, side_c); 51 | } 52 | else 53 | { 54 | double radius; 55 | is >> radius; 56 | 57 | return std::make_shared(figure, radius); 58 | } 59 | } 60 | 61 | int main() 62 | { 63 | std::vector> figures; 64 | for (std::string line; std::getline(std::cin, line); ) 65 | { 66 | std::istringstream is(line); 67 | 68 | std::string command; 69 | is >> command; 70 | if (command == "ADD") 71 | { 72 | figures.push_back(CreateFigure(is)); 73 | } 74 | else if (command == "PRINT") 75 | { 76 | for (const auto& current_figure : figures) 77 | { 78 | std::cout << std::fixed << std::setprecision(3) 79 | << current_figure->Name() << " " 80 | << current_figure->Perimeter() << " " 81 | << current_figure->Area() << std::endl; 82 | } 83 | } 84 | } 85 | return 0; 86 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_3/Triangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Triangle.h" 2 | #include 3 | 4 | std::string Triangle::Name() const 5 | { 6 | return name_; 7 | } 8 | 9 | double Triangle::Perimeter() const 10 | { 11 | return side_A_ + side_B_ + side_C_; 12 | } 13 | 14 | double Triangle::Area() const 15 | { 16 | const double p = 0.5 * (Perimeter()); 17 | 18 | return std::sqrt(p * (p - side_A_) * (p - side_B_) * (p - side_C_)); 19 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_5/Task_3/Triangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Figure.h" 4 | 5 | class Triangle : public Figure 6 | { 7 | public: 8 | Triangle(const std::string& name, const double& side_a, const double& side_b, const double& side_c) 9 | : name_(name), side_A_(side_a), side_B_(side_b), side_C_(side_c){} 10 | 11 | std::string Name() const override; 12 | 13 | double Perimeter() const override; 14 | 15 | double Area() const override; 16 | 17 | private: 18 | const std::string name_; 19 | const double side_A_; 20 | const double side_B_; 21 | const double side_C_; 22 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/condition_parser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "node.h" 7 | 8 | using namespace std; 9 | 10 | shared_ptr ParseCondition(istream& is); 11 | 12 | void TestParseCondition(); -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/database.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "database.h" 5 | 6 | //Добавляем событие в БД 7 | void Database::Add(const Date& date, const string& new_event) 8 | { 9 | if (unique_base_[date].count(new_event) == 0) 10 | { 11 | base_[date].push_back(new_event); 12 | unique_base_[date].insert(new_event); 13 | } 14 | } 15 | //Выводим всю БД в формате День-Событие 16 | void Database::Print(ostream& os) const 17 | { 18 | for (const auto& [date, events] : base_) 19 | { 20 | for (const auto& event : events) 21 | { 22 | os << date << ' ' << event << endl; 23 | } 24 | } 25 | } 26 | //Выводим последнее добавленное событие к указанной дате 27 | //или последнее событие во всей БД 28 | pair Database::Last(const Date& date) const 29 | { 30 | auto it = base_.upper_bound(date); 31 | if (it == base_.begin()) 32 | { 33 | throw invalid_argument(""); 34 | } 35 | 36 | --it; 37 | 38 | return make_pair(it->first, it->second.back()); 39 | } 40 | 41 | ostream& operator<< (ostream& os, const pair& pair) 42 | { 43 | return os << pair.first << ' ' << pair.second; 44 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/date.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "date.h" 6 | 7 | //Парсим дату 8 | Date ParseDate(istream& is) 9 | { 10 | int year, month, day; 11 | is >> year; 12 | is.ignore(1); 13 | is >> month; 14 | is.ignore(1); 15 | is >> day; 16 | 17 | return { year, month, day }; 18 | } 19 | 20 | ostream& operator<< (ostream& os, const Date& date) 21 | { 22 | return os << setw(4) << setfill('0') << date.year_ << '-' << 23 | setw(2) << setfill('0') << date.month_ << '-' << 24 | setw(2) << setfill('0') << date.day_; 25 | } 26 | 27 | bool operator< (const Date& lhs, const Date& rhs) 28 | { 29 | auto lhs_key = tie(lhs.year_, lhs.month_, lhs.day_); 30 | auto rhs_key = tie(rhs.year_, rhs.month_, rhs.day_); 31 | 32 | return lhs_key < rhs_key; 33 | } 34 | 35 | bool operator<= (const Date& lhs, const Date& rhs) 36 | { 37 | auto lhs_key = tie(lhs.year_, lhs.month_, lhs.day_); 38 | auto rhs_key = tie(rhs.year_, rhs.month_, rhs.day_); 39 | 40 | return lhs_key <= rhs_key; 41 | } 42 | 43 | bool operator> (const Date& lhs, const Date& rhs) 44 | { 45 | auto lhs_key = tie(lhs.year_, lhs.month_, lhs.day_); 46 | auto rhs_key = tie(rhs.year_, rhs.month_, rhs.day_); 47 | 48 | return lhs_key > rhs_key; 49 | } 50 | 51 | bool operator>= (const Date& lhs, const Date& rhs) 52 | { 53 | auto lhs_key = tie(lhs.year_, lhs.month_, lhs.day_); 54 | auto rhs_key = tie(rhs.year_, rhs.month_, rhs.day_); 55 | 56 | return lhs_key >= rhs_key; 57 | } 58 | 59 | bool operator== (const Date& lhs, const Date& rhs) 60 | { 61 | auto lhs_key = tie(lhs.year_, lhs.month_, lhs.day_); 62 | auto rhs_key = tie(rhs.year_, rhs.month_, rhs.day_); 63 | 64 | return lhs_key == rhs_key; 65 | } 66 | 67 | bool operator!= (const Date& lhs, const Date& rhs) 68 | { 69 | auto lhs_key = tie(lhs.year_, lhs.month_, lhs.day_); 70 | auto rhs_key = tie(rhs.year_, rhs.month_, rhs.day_); 71 | 72 | return lhs_key != rhs_key; 73 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/date.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | //хранит в себе дату год-месяц-день 8 | class Date 9 | { 10 | public: 11 | Date(int year, int month, int day) : year_(year), month_(month), day_(day) {} 12 | const int year_; 13 | const int month_; 14 | const int day_; 15 | }; 16 | 17 | //парсит дату (год-месяц-день) 18 | //и возвращается готовый класс Date 19 | Date ParseDate(istream& is); 20 | 21 | ostream& operator<< (ostream& os, const Date& date); 22 | 23 | bool operator< (const Date& lhs, const Date& rhs); 24 | bool operator<= (const Date& lhs, const Date& rhs); 25 | bool operator> (const Date& lhs, const Date& rhs); 26 | bool operator>= (const Date& lhs, const Date& rhs); 27 | bool operator== (const Date& lhs, const Date& rhs); 28 | bool operator!= (const Date& lhs, const Date& rhs); -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/node.cpp: -------------------------------------------------------------------------------- 1 | #include "node.h" 2 | #include "date.h" 3 | #include 4 | 5 | bool EmptyNode::Evaluate(const Date& date, const string& event) 6 | { 7 | return true; 8 | } 9 | 10 | bool DateComparisonNode::Evaluate(const Date& date, const string& event) 11 | { 12 | if (cmp_ == Comparison::Less) 13 | { 14 | return date < date_; 15 | } 16 | else if (cmp_ == Comparison::LessOrEqual) 17 | { 18 | return date <= date_; 19 | } 20 | else if (cmp_ == Comparison::Greater) 21 | { 22 | return date > date_; 23 | } 24 | else if (cmp_ == Comparison::GreaterOrEqual) 25 | { 26 | return date >= date_; 27 | } 28 | else if (cmp_ == Comparison::Equal) 29 | { 30 | return date == date_; 31 | } 32 | else if (cmp_ == Comparison::NotEqual) 33 | { 34 | return date != date_; 35 | } 36 | 37 | return false; 38 | } 39 | 40 | bool EventComparisonNode::Evaluate(const Date& date, const string& event) 41 | { 42 | if (cmp_ == Comparison::Less) 43 | { 44 | return event < event_; 45 | } 46 | else if (cmp_ == Comparison::LessOrEqual) 47 | { 48 | return event <= event_; 49 | } 50 | else if (cmp_ == Comparison::Greater) 51 | { 52 | return event > event_; 53 | } 54 | else if (cmp_ == Comparison::GreaterOrEqual) 55 | { 56 | return event >= event_; 57 | } 58 | else if (cmp_ == Comparison::Equal) 59 | { 60 | return event == event_; 61 | } 62 | else if (cmp_ == Comparison::NotEqual) 63 | { 64 | return event != event_; 65 | } 66 | 67 | return false; 68 | } 69 | 70 | bool LogicalOperationNode::Evaluate(const Date& date, const string& event) 71 | { 72 | return logop_ == LogicalOperation::And ? 73 | lhs_->Evaluate(date, event) && rhs_->Evaluate(date, event) : 74 | lhs_->Evaluate(date, event) || rhs_->Evaluate(date, event); 75 | 76 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/node.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "date.h" 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | enum class Comparison 10 | { 11 | Less, 12 | LessOrEqual, 13 | Greater, 14 | GreaterOrEqual, 15 | Equal, 16 | NotEqual, 17 | }; 18 | 19 | enum class LogicalOperation 20 | { 21 | Or, 22 | And, 23 | }; 24 | 25 | class Node 26 | { 27 | public: 28 | bool virtual Evaluate(const Date& date, const string& event) = 0; 29 | }; 30 | 31 | class EmptyNode : public Node 32 | { 33 | public: 34 | bool Evaluate(const Date& date, const string& event) override; 35 | }; 36 | 37 | class DateComparisonNode : public Node 38 | { 39 | public: 40 | DateComparisonNode(Comparison cmp, const Date& date) : cmp_(cmp), date_(date) {} 41 | bool Evaluate(const Date& date, const string& event) override; 42 | private: 43 | const Comparison cmp_; 44 | const Date date_; 45 | }; 46 | 47 | class EventComparisonNode : public Node 48 | { 49 | public: 50 | EventComparisonNode(Comparison cmp, const string& event) : cmp_(cmp), event_(event) {} 51 | bool Evaluate(const Date& date, const string& event) override; 52 | private: 53 | const Comparison cmp_; 54 | const string event_; 55 | }; 56 | 57 | class LogicalOperationNode : public Node 58 | { 59 | public: 60 | LogicalOperationNode(LogicalOperation lop, const shared_ptr& lhs, const shared_ptr& rhs) : logop_(lop), lhs_(lhs), rhs_(rhs) {} 61 | bool Evaluate(const Date& date, const string& event) override; 62 | private: 63 | const LogicalOperation logop_; 64 | const shared_ptr lhs_; 65 | const shared_ptr rhs_; 66 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/test_runner.cpp: -------------------------------------------------------------------------------- 1 | #include "test_runner.h" 2 | 3 | void Assert(bool b, const string& hint) 4 | { 5 | AssertEqual(b, true, hint); 6 | } 7 | 8 | TestRunner::~TestRunner() 9 | { 10 | if (fail_count > 0) 11 | { 12 | cerr << fail_count << " unit tests failed. Terminate" << endl; 13 | exit(1); 14 | } 15 | } -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/test_runner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | template 14 | ostream& operator << (ostream& os, const vector& s) 15 | { 16 | os << "{"; 17 | bool first = true; 18 | for (const auto& x : s) 19 | { 20 | if (!first) 21 | { 22 | os << ", "; 23 | } 24 | first = false; 25 | os << x; 26 | } 27 | return os << "}"; 28 | } 29 | 30 | template 31 | ostream& operator << (ostream& os, const set& s) 32 | { 33 | os << "{"; 34 | bool first = true; 35 | for (const auto& x : s) 36 | { 37 | if (!first) 38 | { 39 | os << ", "; 40 | } 41 | first = false; 42 | os << x; 43 | } 44 | return os << "}"; 45 | } 46 | 47 | template 48 | ostream& operator << (ostream& os, const map& m) 49 | { 50 | os << "{"; 51 | bool first = true; 52 | for (const auto& kv : m) 53 | { 54 | if (!first) 55 | { 56 | os << ", "; 57 | } 58 | first = false; 59 | os << kv.first << ": " << kv.second; 60 | } 61 | return os << "}"; 62 | } 63 | 64 | template 65 | void AssertEqual(const T& t, const U& u, const string& hint = {}) 66 | { 67 | if (t != u) 68 | { 69 | ostringstream os; 70 | os << "Assertion failed: " << t << " != " << u; 71 | if (!hint.empty()) 72 | { 73 | os << " hint: " << hint; 74 | } 75 | throw runtime_error(os.str()); 76 | } 77 | } 78 | 79 | void Assert(bool b, const string& hint); 80 | 81 | class TestRunner 82 | { 83 | public: 84 | template 85 | void RunTest(TestFunc func, const string& test_name) 86 | { 87 | try 88 | { 89 | func(); 90 | cerr << test_name << " OK" << endl; 91 | } 92 | catch (exception& e) 93 | { 94 | ++fail_count; 95 | cerr << test_name << " fail: " << e.what() << endl; 96 | } 97 | catch (...) 98 | { 99 | ++fail_count; 100 | cerr << "Unknown exception caught" << endl; 101 | } 102 | } 103 | 104 | ~TestRunner(); 105 | 106 | private: 107 | int fail_count = 0; 108 | }; -------------------------------------------------------------------------------- /Yellow Belt/Week_6 (Final_project)/token.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | enum class TokenType 8 | { 9 | DATE, 10 | EVENT, 11 | COLUMN, 12 | LOGICAL_OP, 13 | COMPARE_OP, 14 | PAREN_LEFT, 15 | PAREN_RIGHT, 16 | }; 17 | 18 | struct Token 19 | { 20 | const string value; 21 | const TokenType type; 22 | }; 23 | 24 | vector Tokenize(istream& cl); -------------------------------------------------------------------------------- /logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m3nf1s/Modern-Cplusplus/d29d94463d91a42b36b890316106723b2be422a1/logo.jpg --------------------------------------------------------------------------------