From aeeb6e4769f609e01db51451c53eec518e3126be Mon Sep 17 00:00:00 2001 From: "h@di" Date: Tue, 10 Jul 2018 19:16:32 +0430 Subject: [PATCH] add solution --- .gitignore | 59 ++++++++++++++++++++++++ customer.cpp | 56 +++++++++++++++++++++++ customer.h | 27 +++++++++++ food.cpp | 50 +++++++++++++++++++++ food.h | 25 +++++++++++ main.cpp | 99 ++++++++++++++++++++++++++++++++++++++++ makefile | 33 ++++++++++++++ order.cpp | 64 ++++++++++++++++++++++++++ order.h | 38 ++++++++++++++++ restaurant.cpp | 53 ++++++++++++++++++++++ restaurant.h | 25 +++++++++++ system.cpp | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ system.h | 31 +++++++++++++ util.cpp | 17 +++++++ util.h | 9 ++++ 15 files changed, 706 insertions(+) create mode 100644 .gitignore create mode 100644 customer.cpp create mode 100644 customer.h create mode 100644 food.cpp create mode 100644 food.h create mode 100644 main.cpp create mode 100644 makefile create mode 100644 order.cpp create mode 100644 order.h create mode 100644 restaurant.cpp create mode 100644 restaurant.h create mode 100644 system.cpp create mode 100644 system.h create mode 100644 util.cpp create mode 100644 util.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4390365 --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +###C++### + +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + + +###OSX### + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk \ No newline at end of file diff --git a/customer.cpp b/customer.cpp new file mode 100644 index 0000000..fb441df --- /dev/null +++ b/customer.cpp @@ -0,0 +1,56 @@ +#include "customer.h" +#include +#include + +using namespace std; + +Customer::Customer(string _name, long _id, string _location): name(_name), id(_id), location(_location){} + +long Customer::getId() const{ + return id; +} + +string Customer::getName() const{ + return name; +} + +string Customer::getLocation() const{ + return location; +} + +string Customer::getLastBill() const{ + if(!orders.size()) + return "\n"; + return getName() + string(" ") + to_string(getId()) + string("\n") + orders.back().getBill(); +} + +string Customer::getAllBills() const{ + string result = getName() + string(" ") + to_string(getId()) + string("\n"); + for(int i = 0; i < orders.size(); i++) + result += orders[i].getBill() + string("#\n"); + result += string("total purchase ") + to_string(getTotalPurchase()) + string("\n"); + return result; +} + +void Customer::newOrder(){ + orders.push_back(Order(this)); +} + +void Customer::addToOrder(Food *food, Restaurant *restaurant, int num, string personalizations){ + if(!orders.size()) + return; + orders.back().addToOrder(food, restaurant, num, personalizations); +} + +string Customer::getOrderReport() const{ + if(!orders.size()) + return "\n"; + return getName() + string(" ") + to_string(getId()) + string(" ") + to_string(orders.back().getTotalCost()) + string("\n"); +} + +int Customer::getTotalPurchase() const{ + int sum = 0; + for(int i = 0; i < orders.size(); i++) + sum += orders[i].getTotalCost(); + return sum; +} diff --git a/customer.h b/customer.h new file mode 100644 index 0000000..98a6fcc --- /dev/null +++ b/customer.h @@ -0,0 +1,27 @@ +#ifndef CUSTOMER_H +#define CUSTOMER_H + +#include +#include +#include "order.h" + +class Customer{ +private: + std::string name; + long id; + std::vector orders; + std::string location; +public: + Customer(std::string name, long id, std::string location); + long getId() const; + std::string getName() const; + std::string getLocation() const; + std::string getLastBill() const; + std::string getAllBills() const; + void newOrder(); + void addToOrder(Food *, Restaurant *, int num, std::string personalizations); + std::string getOrderReport() const; + int getTotalPurchase() const; +}; + +#endif \ No newline at end of file diff --git a/food.cpp b/food.cpp new file mode 100644 index 0000000..d0f0107 --- /dev/null +++ b/food.cpp @@ -0,0 +1,50 @@ +#include "food.h" +#include + +using namespace std; + +Food::Food(int _id, string _name, Type _type, int _cost): id(_id), name(_name), type(_type), cost(_cost){} + +string Food::getDetails() const{ + return idToString(id) + " " + name + " " + typeToString(type) + " " + to_string(cost); +} + +int Food::getCost() const{ + return cost; +} + +string Food::typeToString(Type type){ + switch(type){ + case Iranian: + return "Iranian"; + case Eastern: + return "Eastern"; + case European: + return "European"; + default: + return ""; + } +} + +string Food::idToString(int id){ + return (id >= 100 ? string("") : (string("0") + (id >= 10 ? string("") : string("0")))) + to_string(id); +} + +int Food::getId() const{ + return id; +} + +Food::Type Food::stringToType(string str){ + if(str == "Iranian") + return Iranian; + else if(str == "Eastern") + return Eastern; + else if(str == "European") + return European; + else + return All; // default +} + +Food::Type Food::getType() const{ + return type; +} diff --git a/food.h b/food.h new file mode 100644 index 0000000..c51cc1c --- /dev/null +++ b/food.h @@ -0,0 +1,25 @@ +#ifndef FOOD_H +#define FOOD_H + +#include + +class Food{ +public: + enum Type{All, Iranian, Eastern, European}; +private: + int id; + std::string name; + int cost; + Type type; + static std::string idToString(int); +public: + Food(int id, std::string name, Type, int cost); + std::string getDetails() const; + int getCost() const; + static std::string typeToString(Type); + static Type stringToType(std::string); + int getId() const; + Type getType() const; +}; + +#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..e231bf2 --- /dev/null +++ b/main.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include "system.h" +#include "util.h" + +#define NEW_SUPER -1 +#define ERRSTR "ERR" + +using namespace std; + +void readDatabase(System &system, string customersFileName, string restaurantsFileName){ + string line; + ifstream restaurantsFileStr(restaurantsFileName, ifstream::in); + int restaurantId = NEW_SUPER; + while(getline(restaurantsFileStr, line)){ + if(line == ""){ + restaurantId = NEW_SUPER; + } + else{ + vector inputParameters = parseString(line, ','); + if(restaurantId == NEW_SUPER){ + restaurantId = atoi(inputParameters[1].c_str()); + system.addRestaurant(inputParameters[0], restaurantId, inputParameters[2]); + } + else{ + system.addFood(restaurantId, atoi(inputParameters[0].c_str()), inputParameters[1], Food::stringToType(inputParameters[2]), atoi(inputParameters[3].c_str())); + } + } + } + restaurantsFileStr.close(); + + ifstream customersFileStr(customersFileName, ifstream::in); + while(getline(customersFileStr, line)){ + while(getline(customersFileStr, line)){ + vector inputParameters = parseString(line, ','); + system.addCustomer(inputParameters[0], atol(inputParameters[1].c_str()), inputParameters.size() > 2 ? inputParameters[2] : ""); + } + } + customersFileStr.close(); +} + +void systemIo(istream &istr, ostream &ostr, System &system){ + string line; + while(getline(istr, line)){ + vector inputParameters = parseString(line, ' '); + if(inputParameters[0] == "menu"){ + ostr << system.getMenu(atoi(inputParameters[1].c_str())); + } + else if(inputParameters[0] == "restaurants"){ + ostr << system.getRestaurantsDetail(inputParameters.size() > 1 ? atol(inputParameters[2].c_str()) : 0); + } + else if(inputParameters[0] == "list"){ + if(inputParameters[1] == "near"){ + ostr << system.listFoods(atol(inputParameters[2].c_str())); + } + else if(inputParameters[1] == "type"){ + ostr << system.listFoods(Food::stringToType(inputParameters[2])); + } + else ostr << ERRSTR << endl; + } + else if(inputParameters[0] == "order"){ + long customerId = atol(inputParameters[1].c_str()); + system.newOrder(customerId); + while(getline(istr, line) && line != "$"){ + inputParameters = parseString(line, ' '); + string personalizations = ""; + for(int i = 2; i < inputParameters.size(); i++){ + if(i > 2) + personalizations += string(" "); + personalizations += inputParameters[i]; + } + system.addToOrder(customerId, atol(inputParameters[0].c_str()), atoi(inputParameters[1].c_str()), personalizations); + } + ostr << system.getOrderReport(customerId); + } + else if(inputParameters[0] == "bill"){ + if(inputParameters[1] == "all"){ + ostr << system.getAllBills(atol(inputParameters[2].c_str())); + } + else{ + ostr << system.getLastBill(atol(inputParameters[1].c_str())); + } + } + else + ostr << ERRSTR << endl; + // ostr << endl; + } +} + +int main(){ + System system; + + readDatabase(system, "customers.txt", "restaurants.txt"); + systemIo(cin, cout, system); + + return 0; +} \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..cac5718 --- /dev/null +++ b/makefile @@ -0,0 +1,33 @@ +CC=g++ +CF= +CCF=-c + +a.out: main.o customer.o food.o restaurant.o util.o order.o system.o + $(CC) $(CF) main.o customer.o food.o restaurant.o util.o order.o system.o -o a.out; + +main.o: main.cpp customer.h food.h restaurant.h util.h order.h system.h + $(CC) $(CF) $(CCF) main.cpp + +customer.o: customer.cpp customer.h util.h order.h + $(CC) $(CF) $(CCF) customer.cpp + +food.o: food.cpp food.h util.h + $(CC) $(CF) $(CCF) food.cpp + +restaurant.o: restaurant.cpp restaurant.h food.h util.h food.h + $(CC) $(CF) $(CCF) restaurant.cpp + +order.o: order.cpp order.h util.h customer.h + $(CC) $(CF) $(CCF) order.cpp + +system.o: system.cpp system.h util.h customer.h restaurant.h + $(CC) $(CF) $(CCF) system.cpp + +util.o: util.cpp util.h + $(CC) $(CF) $(CCF) util.cpp + +test: a.out + ./a.out + +clean: + rm .DS_Store *.o a.out \ No newline at end of file diff --git a/order.cpp b/order.cpp new file mode 100644 index 0000000..a758b92 --- /dev/null +++ b/order.cpp @@ -0,0 +1,64 @@ +#include "order.h" +#include "food.h" +#include "restaurant.h" +#include "system.h" +#include +#include + +using namespace std; + +SubOrder::SubOrder(Food *_food, Restaurant *_restaurant, int _num, string _personalizations) + : food(_food), num(_num), personalizations(_personalizations), restaurant(_restaurant){} + +string SubOrder::getBill() const{ + return to_string(restaurant->getId()) + food->getDetails() + string(" ") + to_string(num) + + string(" ") + to_string(num * food->getCost()) + ((personalizations != "") ? string(" ") + personalizations : string("")) + string("\n"); +} + +int SubOrder::getCost() const{ + return food->getCost() * num; +}; + +bool SubOrder::isNear(const Customer &customer) const{ + return System::isNear(customer, *(restaurant)); +}; + +int Order::getPureTotalCost() const{ + int sum = 0; + for(int i = 0; i < foods.size(); i++) + sum += foods[i].getCost(); + return sum; +} + +int Order::getTotalCost() const{ + return getPureTotalCost() + getDeliveryCost(); +} + +int Order::getDeliveryCost() const{ + return (getPureTotalCost() > 100000 || isNear()) ? 0 : 5000; +} + +Order::Order(Customer *_customer, std::vector _foods): customer(_customer){ + for(int i = 0; i < _foods.size(); i++) + foods.push_back(_foods[i]); +} + +void Order::addToOrder(Food *food, Restaurant *restaurant, int num, std::string personalizations){ + foods.push_back(SubOrder(food, restaurant, num, personalizations)); +} + +string Order::getBill() const{ + string result; + for(int i = 0; i < foods.size(); i++) + result += foods[i].getBill(); + result += "delivery cost " + to_string(getDeliveryCost()) + string("\n"); + result += "total cost " + to_string(getTotalCost()) + string("\n"); + return result; +} + +bool Order::isNear() const{ + for(int i = 0; i < foods.size(); i++) + if(!foods[i].isNear(*(customer))) + return false; + return true; +} diff --git a/order.h b/order.h new file mode 100644 index 0000000..3714e53 --- /dev/null +++ b/order.h @@ -0,0 +1,38 @@ +#ifndef ORDER_H +#define ORDER_H + +#include +#include + +class Customer; +class Food; +class Restaurant; + +class SubOrder{ +private: + Food* food; + Restaurant* restaurant; + int num; + std::string personalizations; +public: + SubOrder(Food *, Restaurant *, int num, std::string personalizations); + std::string getBill() const; + int getCost() const; + bool isNear(const Customer &) const; +}; + +class Order{ +private: + Customer *customer; + std::vector foods; + bool isNear() const; +public: + Order(Customer *, std::vector = std::vector ()); + void addToOrder(Food *, Restaurant *, int num, std::string personalizations); + std::string getBill() const; + int getTotalCost() const; + int getPureTotalCost() const; + int getDeliveryCost() const; +}; + +#endif \ No newline at end of file diff --git a/restaurant.cpp b/restaurant.cpp new file mode 100644 index 0000000..2ede046 --- /dev/null +++ b/restaurant.cpp @@ -0,0 +1,53 @@ +#include "restaurant.h" +#include +#include + +using namespace std; + +Restaurant::Restaurant(string _name, int _id, string _location, vector foods): id(_id), location(_location), name(_name){ + for(int i = 0; i < foods.size(); i++) + menu.push_back(foods[i]); +} + +void Restaurant::addFood(int id, string name, Food::Type type, int cost){ + vector ::iterator i; + for(i = menu.begin(); i < menu.end(); i++) + if(i->getId() > id) + break; + menu.insert(i, Food (id, name, type, cost)); +} + +string Restaurant::getMenu() const{ + string result; + for(int i = 0; i < menu.size(); i++) + result += to_string(id) + menu[i].getDetails() + string("\n"); + return result; +} + +string Restaurant::getLocation() const{ + return location; +} + +int Restaurant::getId() const{ + return id; +} + +Food *Restaurant::findFood(int id){ + for(int i = 0; i < menu.size(); i++){ + if(menu[i].getId() == id) + return &menu[i]; + } + return NULL; +} + +string Restaurant::getName() const{ + return name; +} + +string Restaurant::getListFoods(Food::Type type) const{ + string result; + for(int i = 0; i < menu.size(); i++) + if(type == Food::All || menu[i].getType() == type) + result += to_string(id) + menu[i].getDetails() + string(" ") + getName() + string(" ") + getLocation() + string("\n"); + return result; +} diff --git a/restaurant.h b/restaurant.h new file mode 100644 index 0000000..74a588d --- /dev/null +++ b/restaurant.h @@ -0,0 +1,25 @@ +#ifndef RESTAURANT_H +#define RESTAURANT_H + +#include +#include +#include "food.h" + +class Restaurant{ +private: + int id; + std::string name; + std::string location; + std::vector menu; +public: + Restaurant(std::string name, int id, std::string location, std::vector = std::vector ()); + void addFood(int id, std::string name, Food::Type, int cost); + std::string getMenu() const; + std::string getListFoods(Food::Type = Food::All) const; + int getId() const; + std::string getName() const; + Food *findFood(int id); + std::string getLocation() const; +}; + +#endif \ No newline at end of file diff --git a/system.cpp b/system.cpp new file mode 100644 index 0000000..5c02566 --- /dev/null +++ b/system.cpp @@ -0,0 +1,120 @@ +#include "system.h" +#include +#include + +#define ERRSTR "ERR" + +using namespace std; + +void System::addCustomer(string name, long id, string location){ + customers.push_back(Customer(name, id, location)); +} + +void System::addRestaurant(string name, int id, string location, vector foods){ + vector ::iterator i; + for(i = restaurants.begin(); i < restaurants.end(); i++) + if(i->getId() > id) + break; + restaurants.insert(i, Restaurant(name, id, location, foods)); +} + +void System::addFood(int restaurantId, int foodId, string name, Food::Type type, int cost){ + Restaurant *restaurant = findRestaurant(restaurantId); + if(!restaurant) + return; + restaurant->addFood(foodId, name, type, cost); +} + +void System::newOrder(long customerId){ + Customer *customer = findCustomer(customerId); + if(!customer) + return; + return customer->newOrder(); +} + +void System::addToOrder(long customerId, long foodId, int num, string personalizations){ + Customer *customer = findCustomer(customerId); + Restaurant *restaurant = findRestaurant(foodId / 1000); + Food *food = restaurant->findFood(foodId % 1000); + if(!customer || !restaurant) + return; + return customer->addToOrder(food, restaurant, num, personalizations); +} + +string System::getOrderReport(long customerId){ + Customer *customer = findCustomer(customerId); + if(!customer) + return ERRSTR; + return customer->getOrderReport(); +} + +string System::getLastBill(long customerId){ + Customer *customer = findCustomer(customerId); + if(!customer) + return ERRSTR; + return customer->getLastBill(); +} + +string System::getAllBills(long customerId){ + Customer *customer = findCustomer(customerId); + if(!customer) + return ERRSTR; + return customer->getAllBills(); +} + +bool System::isNear(const Customer &customer, const Restaurant &restaurant){ + return customer.getLocation() == restaurant.getLocation(); +} + +Customer * System::findCustomer(long id){ + for(int i = 0; i < customers.size(); i++) + if(customers[i].getId() == id) + return &customers[i]; + return NULL; +} + +Restaurant * System::findRestaurant(int id){ + for(int i = 0; i < restaurants.size(); i++) + if(restaurants[i].getId() == id) + return &restaurants[i]; + return NULL; +} + +string System::getMenu(int restaurantId){ + Restaurant *restaurant = findRestaurant(restaurantId); + if(!restaurant) + return ""; + return restaurant->getMenu(); +} + +string System::getRestaurantsDetail(long customerId){ + string result = ""; + Customer *customer; + if(customerId){ + customer = findCustomer(customerId); + } + if(customerId && !customer) + return ""; + for(int i = 0; i < restaurants.size(); i++) + if(!customerId || isNear(*customer, restaurants[i])) + result += restaurants[i].getName() + string(" ") + restaurants[i].getLocation() + string(" ") + to_string(restaurants[i].getId()) + string("\n"); + return result; +} + +string System::listFoods(long customerId){ + string result = ""; + Customer *customer = findCustomer(customerId); + if(!customer) + return ""; + for(int i = 0; i < restaurants.size(); i++) + if(isNear(*customer, restaurants[i])) + result += restaurants[i].getListFoods(); + return result; +} + +string System::listFoods(Food::Type type){ + string result = ""; + for(int i = 0; i < restaurants.size(); i++) + result += restaurants[i].getListFoods(type); + return result; +} diff --git a/system.h b/system.h new file mode 100644 index 0000000..ad1434c --- /dev/null +++ b/system.h @@ -0,0 +1,31 @@ +#ifndef SYSTEM_H +#define SYSTEM_H + +#include +#include +#include "customer.h" +#include "restaurant.h" + +class System{ +private: + std::vector customers; + std::vector restaurants; + Customer * findCustomer(long id); + Restaurant * findRestaurant(int id); +public: + void addCustomer(std::string name, long id, std::string location); + void addRestaurant(std::string name, int id, std::string location, std::vector = std::vector ()); + void addFood(int restaurantId, int foodId, std::string name, Food::Type, int cost); + void newOrder(long customerId); + void addToOrder(long customerId, long foodId, int num, std::string personalizations); + std::string getOrderReport(long customerId); + std::string getLastBill(long customerId); + std::string getAllBills(long customerId); + static bool isNear(const Customer &, const Restaurant &); + std::string getMenu(int restaurantId); + std::string getRestaurantsDetail(long customerId = 0); + std::string listFoods(long customerId); + std::string listFoods(Food::Type); +}; + +#endif \ No newline at end of file diff --git a/util.cpp b/util.cpp new file mode 100644 index 0000000..2d15e62 --- /dev/null +++ b/util.cpp @@ -0,0 +1,17 @@ +#include "util.h" +#include +#include + +using namespace std; + +vector parseString(string str, char delimiter){ + vector v; + int start = 0, end; + for(int end = 0; end <= str.size(); end++){ + if(end == str.size()|| str[end] == delimiter){ + v.push_back(str.substr(start, end - start)); + start = end + 1; + } + } + return v; +} diff --git a/util.h b/util.h new file mode 100644 index 0000000..55c4c31 --- /dev/null +++ b/util.h @@ -0,0 +1,9 @@ +#ifndef UTIL_H +#define UTIL_H + +#include +#include + +std::vector parseString(std::string str, char delimiter = ' '); + +#endif \ No newline at end of file