Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <fstream>
- #include <iostream>
- #include <string>
- #include <vector>
- #include <algorithm>
- #include <regex>
- #include <streambuf>
- #include <filesystem>
- #include <sstream>
- #include <iomanip>
- using namespace std;
- template <typename T>
- typename T::size_type levenshtein_distance(const T & src, const T & dst) //Template for Levenshtein distance to work with strings and vectors
- {
- const typename T::size_type m = src.size();
- const typename T::size_type n = dst.size();
- if (m == 0)
- {
- return n;
- }
- if (n == 0)
- {
- return m;
- }
- std::vector<std::vector<typename T::size_type>> matrix(m + 1);
- for (typename T::size_type i = 0; i <= m; ++i)
- {
- matrix[i].resize(n + 1);
- matrix[i][0] = i;
- }
- for (typename T::size_type i = 0; i <= n; ++i)
- {
- matrix[0][i] = i;
- }
- typename T::size_type above_cell, left_cell, diagonal_cell, cost;
- for (typename T::size_type i = 1; i <= m; ++i)
- {
- for (typename T::size_type j = 1; j <= n; ++j)
- {
- cost = src[i - 1] == dst[j - 1] ? 0 : 1;
- above_cell = matrix[i - 1][j];
- left_cell = matrix[i][j - 1];
- diagonal_cell = matrix[i - 1][j - 1];
- matrix[i][j] = std::min(std::min(above_cell + 1, left_cell + 1), diagonal_cell + cost);
- }
- }
- return matrix[m][n];
- }
- #include <Windows.h>
- using namespace std;
- using namespace experimental::filesystem;
- HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); //Console address to change text color
- inline bool print_str(string str, int k, int n) //Function for printing strings in specific color and with set speed
- {
- SetConsoleTextAttribute(hConsole, k);
- for (int l = 0; l < int(str.size()); l++)
- {
- cout << str[l];
- Sleep(n);
- }
- SetConsoleTextAttribute(hConsole, 14);
- return true;
- }
- bool yes_no() //Function for getting choice from user
- {
- bool err = false;
- string temp;
- getline(cin, temp);
- do
- {
- err = false;
- if (temp == "Yes" || temp == "yes" || temp == "y" || temp == "Y") return true; // Returning result for yes answer
- else if (temp == "No" || temp == "no" || temp == "N" || temp == "n") return false; // For no answer
- else
- {
- // If input is incorrect
- print_str("Type [Yes] or [No]: ", 15, 15);
- getline(cin, temp);
- err = true;
- }
- } while (err);
- cout << "An error occurred!" << endl;
- return true;
- }
- string make_path(string str, string folder) //Function for making path to specific folder to work with input files
- {
- string extension = "";
- folder += "/";
- unsigned int j;
- if (str.length() >= 4)
- {
- j = str.length() - 4;
- for (int i = 0; i < 4; i++)
- {
- extension.push_back(str[j]);
- j++;
- }
- }
- if (extension == ".txt")
- str = folder + str;
- else
- str = folder + str + ".txt";
- return str;
- }
- void filling_strings(vector<string>& vec) //Adds space to the end of string to make them equally long for better levenshtein counting
- {
- unsigned int max_l = 0;
- for (unsigned int i = 0; i < vec.size(); i++)
- {
- if (vec[i].length() > max_l)
- max_l = vec[i].size();
- }
- for (unsigned int i = 0; i < vec.size(); i++)
- {
- while (vec[i].length() < max_l)
- vec[i].push_back(' ');
- }
- }
- string shorting_string(string str) //Removes spaces from the end of string for printing
- {
- while (str[str.length() - 1] == ' ')
- str.pop_back();
- return str;
- }
- string vec_search(const vector<string>& vec, const string& str) //Searches closest result from vector of files
- {
- unsigned int i = 0, k = 0, dist = 100;
- while (k < vec.size())
- {
- if (levenshtein_distance(vec[k], str) < dist)
- {
- dist = levenshtein_distance(vec[k], str);
- i = k;
- }
- k++;
- }
- return vec[i];
- }
- bool empty(const string& str) //Checks if user wrote many spaces or just pressed enter
- {
- bool empty = true;
- if (!str.empty())
- {
- for (unsigned int i = 0; i < str.length(); i++)
- {
- if (str[i] != ' ')
- {
- empty = false;
- }
- }
- }
- return empty;
- }
- void files(vector<string>& vec, string& folder) //Searches all files in folder and puts in vector
- {
- for (auto p : directory_iterator(folder))
- {
- vec.push_back(p.path().string());
- }
- filling_strings(vec);
- }
- void check_files(vector<string>& vec, string& folder) //Checks if user added or changed files in folder to work with program without exiting it
- {
- unsigned int i;
- vector<string> vec_2;
- bool same_name = true;
- for (auto p : directory_iterator(folder))
- {
- vec_2.push_back(p.path().string());
- }
- filling_strings(vec_2);
- if (vec_2.size() != vec.size())
- {
- vec.clear();
- vec = vec_2;
- filling_strings(vec);
- }
- else
- {
- if (vec.size() > vec_2.size())
- i = vec_2.size();
- else
- i = vec.size();
- for (unsigned j = 0; j < i; j++)
- {
- if (vec[j] != vec_2[j])
- {
- vec = vec_2;
- return;
- }
- }
- }
- }
- class Elevator{
- public:
- Elevator(int hh, char cc, int mm, int ss, int ee) //Method to initialize variables
- :hours(hh), chr(cc), mins(mm), s_floor(ss), e_floor(ee), distance(set_dist()), time_travel(0), arrival_time_h(0), arrival_time_m(0)
- {
- check();
- set_time_travel();
- set_arrival();
- return;
- };
- Elevator() :hours(0), chr(':'), mins(0), s_floor(1), e_floor(1), distance(0), time_travel(0), arrival_time_h(0), arrival_time_m(0) {}; //Default case
- //Methods to return variables from private state
- int get_hours() const
- {
- return hours;
- }
- char get_chr() const
- {
- return chr;
- }
- int get_mins() const
- {
- return mins;
- }
- int get_s_floor() const
- {
- return s_floor;
- }
- int get_e_floor() const
- {
- return e_floor;
- }
- int get_distance() const
- {
- return distance;
- }
- int get_time_travel() const
- {
- return time_travel;
- }
- int get_arrival_h() const
- {
- return arrival_time_h;
- }
- int get_arrival_m() const
- {
- return arrival_time_m;
- }
- bool operator==(const Elevator& ele_1) const
- {
- return (ele_1.hours == hours &&
- ele_1.mins == mins &&
- ele_1.s_floor == s_floor &&
- ele_1.e_floor == e_floor);
- }
- private:
- void check() //Function for check
- {
- check_hours();
- check_mins();
- check_char();
- //check_floors(); //Remove this command from comments if your building doesn't have basement floors
- }
- void check_hours() //Checks hours
- {
- if (hours < 0 || arrival_time_h < 0)
- {
- print_str("Negative hours, huh? I see you are the clever one. \n", 12, 10);
- throw runtime_error("Type again: ");
- }
- else if (hours > 24 || arrival_time_h > 24)
- {
- print_str("There is no way to have more than 24 hours in day. \n", 12, 10);
- throw runtime_error("Type again: ");
- }
- else if ((hours == 24 && mins < 60) || (arrival_time_h == 24 && mins < 60))
- {
- print_str("Day can't have more than 24, so i changed 24:mins to 00:mins. \n", 11, 10);
- hours = 0;
- }
- }
- void check_mins() //checks minutes
- {
- if (mins < 0 || arrival_time_m < 0)
- {
- print_str("Why would you write negative minutes? World doesn't work like this. \n", 4, 10);
- throw runtime_error("Type again: ");
- }
- else if (mins > 60 || arrival_time_m > 60)
- {
- print_str("No way there is more than 60 minutes in hour. \n", 4, 10);
- throw runtime_error("Type again: ");
- }
- else if (mins == 60 || arrival_time_m == 60)
- {
- print_str("You had 60 minutes, so i changed it to 00 mins and added 1 hours. \n", 3, 10);
- if (mins == 60) {
- mins = 0;
- hours++;
- }
- else
- {
- arrival_time_m = 0;
- arrival_time_h++;
- }
- check_hours();
- }
- }
- void check_char() //Checks char between hours and minutes
- {
- if (chr != ':')
- {
- print_str("Hey, i don't understand, what is this ", 15, 10); cout << chr; print_str(" ? Why did you use it? \n", 15, 10);
- throw runtime_error("Type again: ");
- }
- return;
- }
- void check_floors() //Checks basement floors
- {
- if (s_floor < 1 || e_floor < 1)
- {
- print_str("Do you have basement floors? Sorry, but they are not supported in this program. \n", 2, 10);
- throw runtime_error("Type again: ");
- }
- }
- int set_dist() //Calculates travel distance
- {
- if (s_floor > e_floor)
- distance = s_floor - e_floor;
- else if (e_floor > s_floor)
- distance = e_floor - s_floor;
- else
- {
- print_str("Why would you call elevator and go to the same floor?", 13, 10);
- distance = 0;
- }
- return distance;
- }
- void set_time_travel()
- {
- time_travel = distance*floor_time;
- }
- void set_arrival() //Calculates travel time based on
- {
- arrival_time_h = hours;
- arrival_time_m = mins + time_travel;
- while (arrival_time_m >= 60)
- {
- arrival_time_m -= 60;
- arrival_time_h++;
- }
- while (arrival_time_h >= 24)
- arrival_time_h -= 24;
- check();
- }
- int hours, mins, s_floor, e_floor, distance, time_travel, arrival_time_h, arrival_time_m;
- double floor_time = 1.2; //In minutes, yes, very slow elevator. Or very high ceilings in floors
- char chr;
- };
- ostream& operator<< (ostream& os, const Elevator& tm) //Reloading output operator
- {
- char old_fill = os.fill('0');
- os << setw(2) << tm.get_hours() << tm.get_chr() << setw(2) << tm.get_mins(); print_str(" - Time of elevator call", 15, 10);
- os << endl << tm.get_s_floor(); print_str(" - Floor where elevator was called", 15, 10);
- os << endl << tm.get_e_floor(); print_str(" - Destination floor", 15, 10);
- os << endl << tm.get_distance(); print_str(" - Travel distance", 15, 10);
- os << endl << tm.get_time_travel(); print_str(" minutes - Travel time", 15, 10);
- os << endl << tm.get_arrival_h() << tm.get_chr() << tm.get_arrival_m(); print_str(" - Arrival time", 15, 10);
- os << endl << setfill(old_fill);
- return os;
- }
- ostream& operator<< (ostream& os, const vector<Elevator>& tm) //Reloading output operator for vector class
- {
- for (unsigned int i = 0; i < tm.size(); i++)
- {
- os << tm[i] << endl;
- }
- return os;
- }
- istream& operator>> (istream& is, Elevator& ele) //Reloading of input operator
- {
- int h, m, f1, fe;
- char ch;
- is >> h >> ch >> m >> f1 >> fe;
- if (!is)
- return is;
- try
- {
- ele = Elevator(h, ch, m, f1, fe);
- }catch (runtime_error& e)
- {
- is.clear(ios_base::failbit);
- }
- return is;
- }
- void stats(vector<Elevator>& vec) //Function to get all statistics from class vector and print it
- {
- int all_travel = 0, all_time = 0;
- for (unsigned int i = 0; i < vec.size(); i++)
- {
- all_travel += vec[i].get_distance();
- all_time += vec[i].get_time_travel();
- }
- print_str("Elevator were called ", 15, 10); cout << vec.size(); print_str(" times today.\n", 15, 10);
- print_str("It traveled ", 15, 10); cout << all_travel; print_str(" floors in total.\n", 15, 10);
- print_str("It traveled for ", 15, 10); cout << all_time; print_str(" minutes in total.\n", 15, 10);
- }
- bool call(vector<Elevator>& vec, string& choice) //Function to call different commands
- {
- string help = "help", stat = "stats", clear = "clear", dummy, show = "show all";
- if (levenshtein_distance(choice, help) < 2)
- {
- print_str(
- "Hello, you have used \"help\" command, and here i am.\nYou can type \"help\" to see this text again, you can also use:\n",
- 10, 10);
- cout << "\"stats\" ";
- print_str(
- "to call overall stats for this day, how many times elevator was called and total travel distance;\n",
- 10, 10);
- cout << "\"clear\" ";
- print_str("to clear today's calls and start a \"New Day\";\n", 10, 10);
- cout << "\"show all\" ";
- print_str(" to show all saved variables.\n", 10, 10);
- print_str("You can call them whenever you want (except when you need to write file's name)\n", 10, 15);
- print_str("Press Enter to continue.", 7, 10);
- getline(cin, dummy);
- return true;
- }
- else if (levenshtein_distance(choice, stat) < 2)
- {
- stats(vec);
- print_str("Press Enter to continue.", 7, 10);
- getline(cin, dummy);
- return true;
- }
- else if (levenshtein_distance(choice, clear) < 2)
- {
- vec.clear();
- print_str("Day was cleared.\n", 15, 10);
- print_str("Press Enter to continue.", 7, 10);
- getline(cin, dummy);
- return true;
- }
- else if (levenshtein_distance(choice, show) < 3)
- {
- print_str("All variables:\n", 15, 10);
- cout << vec;
- print_str("Press Enter to continue.", 7, 10);
- getline(cin, dummy);
- return true;
- }
- return false;
- }
- bool yes_no(vector<Elevator>& vec, const string& mes) //Function to get answer from user from before, but reloaded with different variables and calling previous function
- {
- bool err = false, cal;
- string temp;
- print_str(mes, 15, 10);
- getline(cin, temp);
- do
- {
- cal = call(vec, temp);
- err = false;
- if (cal)
- {
- while (cal)
- {
- print_str(mes, 15, 10);
- getline(cin, temp);
- cal = call(vec, temp);
- }
- }
- if (temp == "Yes" || temp == "yes" || temp == "y" || temp == "Y") return true; // Returning result for yes answer
- else if (temp == "No" || temp == "no" || temp == "N" || temp == "n") return false; // For no answer
- else
- {
- // If input is incorrect
- print_str("Type [Yes] or [No]: ", 15, 15);
- getline(cin, temp);
- err = true;
- }
- } while (err);
- cout << "An error occurred!" << endl;
- return true;
- }
- void file_work(vector<string>& vec, string& read, string folder) //Function to do all work with files
- {
- files(vec, folder);
- string file;
- print_str("Write file's name: ", 15, 10);
- do
- {
- getline(cin, file);
- } while (empty(file) && cout << "Why would you write nothing? Type again: ");
- ifstream in;
- check_files(vec, folder);
- in.open(make_path(file, folder));
- if (!in.is_open()) //If file isn't open, it asks user if he meant file
- {
- print_str("Did you mean \"", 15, 10);
- cout << shorting_string(vec_search(vec, make_path(file, folder)));
- print_str("\"?\n", 15, 10);
- if (yes_no())
- in.open(vec_search(vec, make_path(file, folder)));
- }
- read.assign((istreambuf_iterator<char>(in)), //Assigns to string from input buffer
- istreambuf_iterator<char>());
- }
- int main()
- {
- print_str("Hello, you can write elevator schedule here, it will save all of them until you reset it.\nType \"help\" for mote info\n", 11, 10);
- vector<Elevator> day;
- vector<string> files;
- Elevator ele, base;
- string dummy, read;
- do
- {
- if (yes_no(day, "Do you want to read from file?\n"))
- {
- file_work(files, read, "Input");
- cout << read << endl;
- istringstream in(read);
- while (in)
- {
- in >> ele;
- day.push_back(ele);
- }
- day.pop_back();
- }
- else
- {
- print_str("Write your stuff: ", 15, 10);
- do
- {
- getline(cin, dummy);
- call(day, dummy);
- istringstream in(dummy);
- while (in)
- {
- in >> ele;
- day.push_back(ele);
- }
- day.pop_back();
- }
- while (ele == base && print_str("Type again: ", 15, 10));
- }
- ele = base;
- } while (yes_no(day, "Continue?\n"));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement